Устранение NULL при использовании CASE в операторе SQL Server SELECT - PullRequest
2 голосов
/ 16 сентября 2010

У меня есть большой грязный отчет, который объединяет 5 таблиц. В одной таблице есть один столбец, который используется для нескольких различных значений - по сути, это столбец «тегов», где теги используются творчески, в зависимости от того, какие разные метаданные хотят использовать пользователи.

В результате мой запрос к отчету возвращает 3 практически идентичные строки, которые отличаются только в столбце «тег»; например, я мог бы получить:

NAME TAG EMAIL  
BOB  A   BOB@EXAMPLE.COM  
BOB  B   BOB@EXAMPLE.COM  
BOB  C   BOB@EXAMPLE.COM  

То, что я хотел бы сделать, это разделить содержимое столбца TAG, который будет возвращен как 3 отдельных столбца из запроса, например:

NAME A B C EMAIL
BOB  A B C BOB@EXAMPLE.COM

Поэтому я попытался использовать функциональность SQL SERVER CASE / WHEN для этого; Я говорю, например, когда значение столбца Tag равно «A», вернуть его в столбец «A»; если это «B», поместите его в «B»; и т.д. Я думал, что это вернет вышеупомянутое, но вместо этого он дает мне это:

NAME A    B    C    EMAIL
BOB  A    NULL NULL BOB@EXAMPLE.COM
BOB  NULL B    NULL BOB@EXAMPLE.COM
BOB  NULL NULL C    BOB@EXAMPLE.COM

Что явно не идеально.

Есть мысли, гении переполнения стека?

Ответы [ 2 ]

6 голосов
/ 16 сентября 2010

Вам необходимо pivot данных.

;with Report (name, tag, email) as
(
select 'BOB', 'A', 'BOB@BOB.COM' union
select 'BOB', 'B', 'BOB@BOB.COM' union
select 'BOB', 'C', 'BOB@BOB.COM' 
)
select * from Report
pivot 
( min(tag) for  tag in ([A], [B], [C]))  
as pvt

И результат выполнения вышеуказанного запроса будет следующим:

NAME    EMAIL         A  B  C
-----------------------------
BOB     BOB@BOB.COM   A  B  C
5 голосов
/ 16 сентября 2010

попробуйте это:

   Select Name,
    Min (Case When tag = 'A' Then Tag End) A,
    Min (Case When tag = 'B' Then Tag End) B,
    Min (Case When tag = 'C' Then Tag End) C,
    email
   From tableName
   Group By Name, email

РЕДАКТИРОВАТЬ: объяснить ...
Каждый раз, когда вы используете Group By, вы сообщаете обработчику запросов, что вы хотите, чтобы он агрегировал результаты в «сегменты»", где каждый сегмент определяется уникальными значениями в столбцах [или выражениях], определенных в предложении Group By.Это означает, что конечный набор результатов будет иметь одну и только одну строку для каждого уникального набора значений в тех столбцах [или выражениях], которые определены в Group By.Для всех других столбцов или выражений, используемых в запросе (кроме тех, которые определены в Group By), должно быть выражением, основанным на функции агрегирования (например, Count (), Sum (), Avg (), Min (), Max () и т. Д.), Которые создают значение на основе вычисления, которое будет применяться ко всем строкам в предварительно агрегированном наборе результатов.Если, например, я наберу Group By первый символ фамилии:

Select Left(LastName, 1), Count(*), 
   Sum(Salaray, Avg(Height), 
   Min(DateOfBirth), etc.
  From Table
  Group By Left(LastName, 1)

, то я получу максимум 26 строк в выводе (по одной на каждую букву в алфавите) и вседругие столбцы в моих выходных данных должны основываться на некоторой функции агрегирования, которая должна применяться ко всем строкам в исходном наборе, где фамилия начинается с «A», затем ко всем строкам, где фамилия начинается с qa «B» и т. д..

В вашей задаче Group By используется просто для того, чтобы ограничить выходной набор одной строкой для каждого отдельного пользователя и сообщения электронной почты. Как только это будет сделано, в других столбцах оператора Select будет только одна строка.необходимо иметь Min(), [Max() будет работать так же хорошо), только для того, чтобы удовлетворить синтаксические требования, упомянутые в полужирный курсив выше. В вашем случае,в наборе будет только одна ненулевая строка, поэтому взятие Min () или Max () необходимо только из-за синтаксического требования ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...