Некоторые вопросы SQL - PullRequest
       23

Некоторые вопросы SQL

2 голосов
/ 29 октября 2009

Я использую SQL годами, но в основном использую конструктор запросов в SQL Studio (и т. Д.) Для составления своих запросов. Недавно я нашел время, чтобы действительно «узнать», что все делает, и поставил перед собой следующие довольно простые задачи. Прежде чем я начну, я хотел бы спросить сообщество SOF о своих мыслях о вопросах, возможных ответах и ​​любых советах, которые они могут иметь.

Вопросы:

  1. Найти все записи с дубликатом в определенном столбце (например, идентификатор ссылки в более чем 1 записи по всей таблице)
  2. Сумма SUM из связанной таблицы в том же запросе (выбрать в виде выбора?)
  3. Объясните разницу между 4 соединениями; ВЛЕВО, ПРАВО, НАРУЖНЫЙ, ВНУТРЕННИЙ
  4. Копирование данных из одной таблицы в другую на основе критериев SELECT и WHERE

Вход приветствуется и ценится.

Chris

Ответы [ 3 ]

1 голос
/ 29 октября 2009

Я рекомендую вам начать с изучения некоторых руководств по этой теме. Ваши вопросы не являются редкими вопросами для тех, кто переходит с SQL на начинающий на средний уровень. SQLZoo является отличным ресурсом для изучения SQL, поэтому подумайте о следующем.

В ответ на ваши вопросы:

1) Найти все записи с дубликатом в определенном столбце

Здесь есть два шага: найти дубликаты записей и выбрать эти записи. Чтобы найти дубликаты записей, вы должны делать что-то вроде:

select possible_duplicate_field, count(*) 
from   table 
group by possible_duplicate_field 
having count(*) > 1

Здесь мы выбираем все из таблицы, затем группируем ее по полю, которое мы хотим проверить на наличие дубликатов. Затем функция подсчета подсчитывает количество элементов в этой группе. Предложение HAVING указывает, что мы хотим отфильтровать ПОСЛЕ группировки, чтобы показать только группы, которые имеют более одной записи.

Само по себе это хорошо, но не дает реальных записей, в которых есть эти значения. Если бы вы знали повторяющиеся значения, вы бы написали:

select * from table where possible_duplicate_field = 'known_duplicate_value'

Мы можем использовать SELECT внутри выбора, чтобы получить список совпадений:

select * 
from table 
where possible_duplicate_field in (
  select possible_duplicate_field 
  from   table 
  group by possible_duplicate_field 
  having count(*) > 1
)

2) Сумма SUM из связанной таблицы в том же запросе

Это простое соединение между двумя таблицами с суммой двух:

select sum(tableA.X + tableB.Y) 
from  tableA 
join  tableB on tableA.keyA = tableB.keyB

То, что вы делаете здесь - это объединение двух таблиц, где эти две таблицы связаны ключевым полем. В этом случае это естественное объединение, которое работает так, как вы ожидаете (т.е. получите все из левой таблицы, в которой есть соответствующая запись в правой таблице).

3) Объясните разницу между 4 соединениями; ВЛЕВО, ПРАВО, НАРУЖНЫЙ, ВНУТРЕННИЙ

Рассмотрим две таблицы A и B. Понятия «LEFT» и «RIGHT» в этом случае немного понятнее, если вы читаете SQL слева направо. Итак, когда я говорю:

select x from A join B ...

Левая таблица - «А», а правая - «В». Теперь, когда вы явно говорите «LEFT» в SQL-выражении, вы объявляете, какая из двух таблиц, к которым вы присоединяетесь, является основной. Под этим я подразумеваю следующее: какую таблицу я сначала сканирую? Кстати, если вы опустите LEFT или RIGHT, то SQL неявно использует LEFT.

Для INNER и OUTER вы заявляете, что делать, если совпадений не существует ни в одной из таблиц. INNER заявляет, что вы хотите, чтобы все в первичной таблице (как объявлено с использованием LEFT или RIGHT), где есть соответствующая запись во вторичной таблице. Следовательно, если первичная таблица содержит ключи «X», «Y» и «Z», а вторичная таблица содержит ключи «X» и «Z», то INNER будет возвращать только записи «X» и «Z» из две таблицы.

Когда используется OUTER, мы говорим: дай мне все из первичной таблицы и все, что совпадает со вторичной таблицей. Следовательно, в предыдущем примере мы получили бы записи «X», «Y» и «Z» в наборе выходных записей. Однако в полях должны быть значения NULL, которые должны были быть получены из вторичной таблицы для значения ключа "Y", поскольку он не существует во вторичной таблице.

4) Копировать данные из одной таблицы в другую на основе критериев SELECT и WHERE

Это довольно тривиально, и я удивлен, что вы никогда не сталкивались с этим. Это простой вложенный оператор SELECT в операторе INSERT (это может не поддерживаться вашей базой данных - если нет, попробуйте следующий вариант):

insert into new_table select * from old_table where x = y

Предполагается, что таблицы имеют одинаковую структуру. Если у вас разные структуры, вам нужно указать столбцы:

insert into new_table (list, of, fields) 
    select list, of, fields from old_table where x = y
1 голос
/ 29 октября 2009

Допустим, у вас есть 2 таблицы с именем:

  • [OrderLine] со столбцами [Id, OrderId, ProductId, Qty, Status]
  • [Продукт] с [Идентификатор, Имя, Цена]

1) вся строка заказа команды имеет более 1 строки (технически это то же самое, что поиск дубликатов в OrderId :):

select OrderId, count(*) 
from OrderLine
group by OrderId
having count(*) > 1

2) общая стоимость для всей строки заказа 1000

select sum(p.Price * ol.Qty) as Price
from OrderLine ol
inner join Product p on ol.ProductId = p.Id
where ol.OrderId = 1000

3) разница между объединениями:

  • внутреннее соединение b => взять все a, которые совпадают с b. если b не найдено, a не будет возвращено
  • соединение слева b => взять все a, сопоставить их с b, включить a, даже если b не найдено
  • правое соединение b => b левое соединение a
  • внешнее соединение b => (левое соединение b) объединение (правое соединение b)

4) скопировать строки заказа в таблицу истории:

insert into OrderLinesHistory
(CopiedOn, OrderLineId, OrderId, ProductId, Qty)
select 
  getDate(), Id, OrderId, ProductId, Qty
from 
  OrderLine
where 
  status = 'Closed'
0 голосов
/ 29 октября 2009

Чтобы ответить на вопрос № 4 и, возможно, показать хоть какое-то понимание SQL и тот факт, что это не HW, просто я пытаюсь изучить лучшие практики;

SET NOCOUNT ON;
DECLARE @rc int
if @what = 1
    BEGIN
        select id from color_mapper where product = @productid and color = @colorid;
        select @rc = @@rowcount
        if @rc = 0
        BEGIN
            exec doSavingSPROC @colorid, @productid;
        END
    END
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...