2015-01-24 2 views
0

У меня есть таблица 'order', содержащая сводную информацию о заказе и таблицу 'orderItem' с каждым элементом заказа.SQL SUM Query возвращает повторяющиеся строки в результате

Моя проблема: при выборе суммы столбца «orderQTY» из таблицы «Заказ» я получаю неверную сумму, если я присоединяюсь к таблице orderItem.

Первый запрос ниже дает мне правильную сумму. Однако, как только я добавляю соединение к orderItem, результат суммы неправильно дублирует столбец «orderqty» для каждой записи orderitem.

nb: Я знаю, что нижеследующее не использует соединение и не является необходимым. Я удалил предложения, ссылающиеся на объединенную таблицу, чтобы упростить вопрос .

--RETURNS Correct value 
select sum(o.orderqty) 
from [order] o 

--RETURNS the sum containing duplicates of o.orderqty 
select sum(o.orderqty) 
from [order] o 
join OrderItem oi on o.Id = oi.OrderId 

- добавление уточнение: ----
Я хотел суммировать столбец «OrderQty» из таблицы «порядка» во время присоединения к OrderItem например:

Там будет несколько ТоварыЗаказа для каждого ордера, но я хочу, чтобы, очевидно, только счет countqty из таблицы заказов один раз за заказ.

select sum(o.ordertotal) 
from [order] o with(NOLOCK) 
join OrderItem oi on o.Id = oi.OrderId 
where oi.mycolumn = 1 

или же мне нужно сделать что-то вроде:

select sum(o.ordertotal) 
from [order] o with(NOLOCK) 
where o.id in (select orderid from orderitem where x = y) 
+2

да, это ожидаемое поведение, используйте 1-ый запрос –

+1

, что вы пытаетесь сделать? получать информацию из строки заказа и таблицы заказов в одном запросе? – Beth

+0

Что использует orderqty для запроса? Какие строки вы запрашиваете с помощью запроса? Можете ли вы просто использовать «o.orderqty»? Если вы не знаете, как написать запрос для чего хотите, тогда вам нужно описать, что вы хотите на английском, и/или привести примеры. – philipxy

ответ

4

Он возвращает различные результаты, поскольку join умножает число строк или фильтрует строки, оба из которых влияют на сумму. Непонятно, что вы действительно хотите сделать. Если вы хотите только сумму количеств заказов, которые имеют OrderLines, то использование существует:

select sum(o.orderqty) 
from [order] o 
where exists (select 1 
       from OrderItem oi 
       where o.Id = oi.OrderId 
      ); 
+0

@RonSmith. , , Если кто-то хочет повлиять на мое поведение в комментариях, они бы гораздо лучше сказали, в чем проблема, чем анонимно downvote. –

+0

Спасибо за помощь, я уточнил вопрос (надеюсь) выше. Я понимаю, что запись заказа возвращается для каждого заказа, и каждый orderitem (которого будет много. Я не понимаю, как обойти проблему без удаления соединения? – art

+0

адаптировали ваш ответ, который теперь возвращает правильное значение, что было очень полезно, учитывая мое, очевидно, плохое описание проблемы. – art

0

Вы можете суммировать один раз в группировке (в данном случае order.id) с помощью функции row_number:

select sum(orderqty) 
from (
    select 
     case row_number() over(partition by o.Id order by o.id) 
      when 1 then orderqty 
      else 0 
     end as orderqty 
    from [order] o 
     join OrderItem oi on o.Id = oi.OrderId 
    ) o 
0

Объединяет работу для создания набора результатов, который объединяет данные из нескольких таблиц. Затем SQL управляет агрегатными функциями и предложением where по этому объединенному набору результатов. Итак, представьте, у вас есть 2 порядка, 1 с одного пункта и 1 с 2 пунктов:

// Order table 
OrderId OrderQty 
1   5 
2   3 

// OrderItem table 
OrderId ItemId 
1   1 
2   1 
2   2 

Ваш присоединиться даст вам этот результат:

OrderId OrderQty OrderId ItemId 
1   5   1   1 
2   3   2   1 
2   3   2   2 

Итак, когда вы SUM(OrderQty), вы получите 11 вместо 8 который, я думаю, вы хотите. Ссылка на другую таблицу не имеет смысла в этом случае ...

0

Предложение FROM (действует так, как будто оно) вычисляет промежуточный table.

Выражение предложения SELECT,

sum(o.orderqty) 

не означает "сумму orderqty колонке таблицы o". Это означает «сумма столбца o.orderqty промежуточной таблицы, сгенерированной предложением FROM».

Вот пример таблицы:

// [order] 
Id orderqty 
1 33 
2 66 

// OrderItem 
OrderId ItemId 
2  7 
1  8 
1  9 

Вот второй запрос:

select sum(o.orderqty) 
from [order] o 
join OrderItem oi on o.Id = oi.OrderId 

Сначала ОТ вычисляет «векторное произведение», который имеет все возможные комбинации строки из таблиц вы ПРИСОЕДИНИТЬСЯ. Таким образом, каждая строка имеет подземелье из каждой таблицы. В каждом подстроке есть имена столбцов, такие как имена столбцов исходной таблицы, но с именем его исходной таблицы или псевдонимом с префиксом точки. (Если нет никакой двусмысленности вам не нужно упоминать префикс и точка обратиться к FROM колонке пункт таблицы.)

// [order] o join OrderItem oi 
o.Id o.orderqty oi.OrderId oi.ItemId 
    1  33   2   7 
    1  33   1   8 
    1  33   1   9 
    2  66   2   7 
    2  66   1   8 
    2  66   1   9 

Тогда строки, которые не УНС и WHERE удаляются:

// [order] o join OrderItem oi on o.Id = oi.OrderId 
o.Id o.orderqty oi.OrderId oi.ItemId 
    1  33   1   8 
    1  33   1   9 
    2  66   2   7 

Это промежуточная таблица FROM второго запроса, которую использует SELECT. Вот первый запрос от промежуточной таблицы, что его ВЫБОР использует:

// [order] o 
o.Id o.orderqty 
    1  33 
    2  66 

Так СУММА второго запроса (в o.orderqty) составляет 33 + 33 + 66, а первый запрос является 33 + 66. Поскольку вы хотите, чтобы SUM для таблицы предложений FROM, которая [order], вы хотите получить первый запрос.

(Мы также можем описать это на нарисуй по присоединиться основе, что позволяет нам объяснить, как LEFT JOIN отличается от INNER JOIN, CROSS JOIN и «» и как USING и NATURAL сделать разницу.)

Re update: Вы не объяснили, какие строки вы хотите вернуть из своего запроса. Может быть, вы хотите:

select oi.Id, oi.orderId, o.orderqty, ... 
from [order] o 
join OrderItem oi on o.Id = oi.OrderId 

или

select ..., (select sum(orderqty) from [order]) as totalqty, ... 
Смежные вопросы