2009-09-09 3 views
4

У меня есть запрос, который возвращает набор результатов аналогичен приведенному нижеКак получить отдельные значения из столбцов?

 A | B | C | D 
    -----|----|----|----- 
1 abc | d0 | e0 | true 
2 def | d0 | e1 | true 
3 ghi | d0 | e2 | true 
4 jkl | d1 | e1 | true 
5 mno | d2 | e2 | false 

В колонке А каждое значение является уникальным. но столбцы B, C, D имеют несколько повторяющихся значений. Я хочу все значения столбца A, но различные значения столбца B, C, D.

Ожидаемый результат что-то подобное

 A | B | C | D 
    -----|---- |---- |----- 
1 abc | d0 | e0 | true 
2 def | NULL| e1 | NULL 
3 ghi | NULL| NULL| NULL 
4 jkl | d1 | NULL| NULL 
5 mno | d2 | e2 | false 

Единственное ограничение, я хочу, чтобы добиться этого в едином операторе выбора. Нет вложенных операторов Select.

+1

Почему 'C' является' NULL' в строке '3'? – Quassnoi

ответ

1
SELECT A, 
     CASE 
     WHEN EXISTS 
       (
       SELECT NULL 
       FROM mytable mi 
       WHERE mi.id < mo.id 
         AND mi.b = mo.b 
       ) THEN NULL 
     ELSE B 
     END AS B, 
     CASE 
     WHEN EXISTS 
       (
       SELECT NULL 
       FROM mytable mi 
       WHERE mi.id < mo.id 
         AND mi.c = mo.c 
       ) THEN NULL 
     ELSE c 
     END AS c, 
     CASE 
     WHEN EXISTS 
       (
       SELECT NULL 
       FROM mytable mi 
       WHERE mi.id < mo.id 
         AND mi.d = mo.d 
       ) THEN NULL 
     ELSE d 
     END AS d 
FROM mytable mo 
+0

Да, что-то вроде этого. Не забудьте поместить фильтры не только в предложение from внешнего запроса, но и ко всем подзапросам. –

+1

Вам нужен заказ, где вы заказываете A, B, C, D. Если вы заказываете по-другому, строка, где отображается одиночное значение B, C или D, может быть не первой. Тогда вы на самом деле не знаете, какая ценность была там. –

+0

Откуда возникает столбец «id»? мне кажется, что OP просто показывает номера строк (без имени столбца или тире) –

0

Что вам нужно на самом деле против природы sql. В sql результат не зависит от заказа.

Даже если вы найдете способ получить такой результат (например, предоставленный Quassnoi), я бы избегал делать это в SQL.

+0

Не согласен, если вы можете сделать это в запросе, сделайте это. Посмотрите на мой ответ, чтобы понять, насколько это легко достичь. Это не намного сложнее обычного выбора из таблицы, используя row_number(), чтобы найти первое вхождение каждого значения. –

+0

Просто потому, что вы можете не значит, что вам нужно. Вам также необходимо учитывать производительность, ремонтопригодность и т. Д. «Can» = «should» слишком неинтересен. ИМХО. – MatBailie

+0

@ Dems, обрабатывать набор в SQL или loop в клиентском приложении? Когда это возможно, мне нравится обрабатывать набор в SQL, и так происходит с этим этим запросом. –

3

попробовать это:

DECLARE @YourTable table (A char(3), B char(2), C char(2), D varchar(5)) 
INSERT INTO @YourTable VALUES ('abc','d0','e0','true') 
INSERT INTO @YourTable VALUES ('def','d0','e1','true') 
INSERT INTO @YourTable VALUES ('ghi','d0','e2','true') 
INSERT INTO @YourTable VALUES ('jkl','d1','e1','true') 
INSERT INTO @YourTable VALUES ('mno','d2','e2','false') 


SELECT 
    A 
    ,CASE WHEN ROW_NUMBER() OVER(PARTITION BY B ORDER BY A,B)=1 THEN B ELSE NULL END AS B 
    ,CASE WHEN ROW_NUMBER() OVER(PARTITION BY C ORDER BY A,C)=1 THEN C ELSE NULL END AS C 
    ,CASE WHEN ROW_NUMBER() OVER(PARTITION BY D ORDER BY A,D)=1 THEN D ELSE NULL END AS D 
    FROM @YourTable 
    ORDER BY A,B,C,D 

ВЫВОД:

A B C D 
---- ---- ---- ----- 
abc d0 e0 true 
def NULL e1 NULL 
ghi NULL e2 NULL 
jkl d1 NULL NULL 
mno d2 NULL false 

(5 row(s) affected) 
Смежные вопросы