У меня есть запрос на возврат размеров упаковки в M2 (квадратных метрах) и UN (единицы). В текущем запросе он возвращает две разные строки, потому что я использую CASE WHEN. Это запрос:

SELECT DISTINCT(C.Package) 'Package',
    CASE S.Unity WHEN 'M2' THEN SUM(L.Qt*S.ConvEst) ELSE NULL END 'M2',
    CASE S.Unity WHEN 'UN' THEN SUM(L.Qt) ELSE NULL END 'UN'
FROM 
    PackageTable AS C
INNER JOIN 
    PackageTableRows L ON L.Package = C.Package
INNER JOIN 
    Products S ON S.Product = L.Product
WHERE 
    C.Package = '587496'
GROUP BY 
    C.Package, S.Unity

Такой результат:

enter image description here

Но что мне действительно нужно, так это запрос, который нужно вернуть, выглядит примерно так:

enter image description here

Только с одной строкой. Я знаю, что использую CASE WHEN неправильно, и поэтому мне нужна ваша помощь.

0
Forrobodo 26 Ноя 2021 в 14:38
Почему вы меняете вопрос после того, как Ларну дал ответ, объясняющий, что не так с вашим запросом? Теперь первая часть его ответа недействительна
 – 
Tim Schmelter
26 Ноя 2021 в 15:00
OP редактировался после того, как я сделал комментарий по поводу DISTINCT, а не ответа, @TimSchmelter, хотя я не заметил, что они удалили указанную часть до после , я написал и отправил ответ. (С тех пор я удалил указанные комментарии, потому что расширил их в своем ответе.) Я откатил указанное редактирование, поскольку вы правы, что оно делает ответ недействительным; Обычно не одобряется изменение таких вещей после того, как вы начали получать ответы / комментарии по вашему коду, Forrobodo.
 – 
Larnu
26 Ноя 2021 в 15:01

2 ответа

Лучший ответ

У вас тут несколько проблем. Во-первых, DISTINCT - это не функция, а оператор. DISTINCT влияет на весь набор данных и приводит к возврату только отдельных строк. Это не DISTINCT ({Column Name}), это SELECT DISTINCT {Columns}.

Затем у вас есть оба DISTINCT и GROUP BY; это недостаток. Предложение GROUP BY уже приводит к тому, что ваши данные возвращаются в различных группах, поэтому DISTINCT является как избыточным, так и ненужным накладным расходом. Избавьтесь от DISTINCT. Если вы получаете разные результаты, когда у вас есть DISTINCT с GROUP BY, это явный признак того, что ваше предложение GROUP BY неверно и требует рассмотрения (скорее всего у вас слишком много столбцов в предложении).

Наконец, при выполнении условного агрегирования агрегатная функция должна охватывать все выражение всего CASE, а не выражение в THEN. Это также означает, что вам нужно удалить столбец в предложении WHEN из GROUP BY, поскольку я подозреваю, что единственная причина, по которой он у вас есть, заключается в том, что вы должны были :

Это приводит к:

SELECT C.Package AS Package,
       SUM(CASE S.Unity WHEN 'M2' THEN L.Qt * S.ConvEst END) AS M2,
       SUM(CASE S.Unity WHEN 'UN' THEN L.Qt END) AS UN
FROM dbo.PackageTable C
     INNER JOIN dbo.PackageTableRows L ON L.Package = C.Package
     INNER JOIN dbo.Products S ON S.Product = L.Product
WHERE C.Package = '587496'
GROUP BY C.Package;
2
Larnu 26 Ноя 2021 в 14:56
Это сработало. Спасибо большое за вашу помощь. Теперь я узнал немного больше о SQL.
 – 
Forrobodo
26 Ноя 2021 в 15:02

Это в основном правильно. Вам нужно GROUP BY только на C.Package, чтобы вывести его в одну строку. Для этого он должен возвращать 0 для условий case else, а агрегирование должно производиться по всем условиям case, а не только по мере.

Вот так это будет выглядеть.

SELECT C.Package 'Package',
SUM(CASE S.Unity WHEN 'M2' THEN (L.Qt*S.ConvEst) ELSE 0 END ) as 'M2', 
SUM(CASE S.Unity WHEN 'UN' THEN SL.Qt ELSE 0 END) AS 'UN'
FROM PackageTable AS C
INNER JOIN PackageTableRows L ON L.Package=C.Package
INNER JOIN Products S ON S.Product=L.Product
WHERE C.Package='587496'
GROUP BY C.Package
0
Alex Rajan Samuel 26 Ноя 2021 в 15:17