2017-10-16 103 views
5

Mam tabelę z kolumnami poniżej, i muszę uzyskać wartości, jeśli COD jest powielony, uzyskać wartość inną niż NULL w kolumnie VALUE. Jeśli nie zostanie zduplikowane, może uzyskać NULL VALUE. Na przykład:Jak mogę wybrać różne po jednej kolumnie?

Używam SQL SERVER.

To co mam:

COD ID VALUE 
28 1 NULL 
28 2 Supermarket 
29 1 NULL 
29 2 School 
29 3 NULL 
30 1 NULL 

To jest to, co chcę:

COD ID VALUE 
28 2 Supermarket 
29 2 School 
30 1 NULL 

Co ja staram się robić:

;with A as ( 
(select DISTINCT COD,ID,VALUE from CodId where ID = 2) 
UNION 
(select DISTINCT COD,ID,NULL from CodId where ID != 2) 
)select * from A order by COD 

Odpowiedz

8

Możesz spróbować.

DECLARE @T TABLE (COD INT, ID INT, VALUE VARCHAR(20)) 
INSERT INTO @T 

VALUES(28, 1, NULL), 
(28, 2 ,'Supermarket'), 
(29, 1 ,NULL), 
(29, 2 ,'School'), 
(29, 3 ,NULL), 
(30, 1 ,NULL) 


;WITH CTE AS (
SELECT *, RN= ROW_NUMBER() OVER (PARTITION BY COD ORDER BY VALUE DESC) FROM @T 
) 
SELECT COD, ID ,VALUE FROM CTE 
WHERE RN = 1 

Wynik:

COD   ID   VALUE 
----------- ----------- -------------------- 
28   2   Supermarket 
29   2   School 
30   1   NULL 
1

użyłbym GROUP BY i JOIN. Jeśli nie ma wartości NOT NULL dla COD, należy ją rozwiązać, używając klauzuli w JOIN.

SELECT your_table.* 
FROM your_table 
JOIN (
    SELECT COD, MAX(value) value 
    FROM your_table 
    GROUP BY COD 
) gt ON your_table.COD = gt.COD and (your_table.value = gt.value OR gt.value IS NULL) 
5

Innym rozwiązaniem jest użycie klauzuli koncert WITH TIES z Row_Number()

Przykład

Select top 1 with ties * 
from YourTable 
Order By Row_Number() over (Partition By [COD] order by Value Desc) 

Zwraca

COD ID VALUE 
28 2 Supermarket 
29 2 School 
30 1 NULL 
1

Jeśli można mieć więcej niż jedno non wartość null dla COD to będzie działać

drop table MyTable 

CREATE TABLE MyTable 
    (
    COD INT, 
    ID INT, 
    VALUE VARCHAR(20) 
) 

INSERT INTO MyTable 
VALUES  (28,1, NULL), 
      (28,2,'Supermarket'), 
      (28,3,'School'), 
      (29,1,NULL), 
      (29,2,'School'), 
      (29,3,NULL), 
      (30,1,NULL); 

WITH Dups AS 
    (SELECT COD FROM MyTable GROUP BY COD HAVING count (*) > 1) 

    SELECT MyTable.COD,MyTable.ID,MyTable.VALUE FROM MyTable 
    INNER JOIN dups ON MyTable.COD = Dups.COD 
    WHERE value IS NOT NULL 
    UNION 
    SELECT MyTable.COD,MyTable.ID,MyTable.VALUE FROM MyTable 
    LEFT JOIN dups ON MyTable.COD = Dups.COD 
    WHERE dups.cod IS NULL