2016-07-26 36 views
5

Mam prostą tabelę jednej kolumny z dwiema wartościami. Wybieram go i łączę wartości z różnymi modyfikatorami, ale to po prostu dostaje ostatnią wartość. Czy jestem w nieporozumieniu z DISTINCT?Łączenie wartości kolumn z odrębnymi uzyskuje dziwny wynik

DECLARE @table TABLE(Id int) 
DECLARE @result VARCHAR(MAX) = '' 

INSERT @table VALUES(1), (2) 

SELECT 
    @result = @result + CAST(Id AS VARCHAR(10)) + ',' 
FROM 
    @table 

SELECT @result --— output: 1,2, 

-------same With distinct 
SET @result = '' 

SELECT DISTINCT @result = @result 
     + CAST(Id AS VARCHAR(10)) + ',' 
FROM @table 
SELECT @result --— expected output: 1,2, actual output: 2, why? 

Odpowiedz

4

Szybkie spojrzenie w planie wykonanie (a niektóre zabawy) wykazało mi, że SELECT DISTINCT także sortuje, i do nich można uzyskać maksymalną id.

Na przykład, w

INSERT @table VALUES(1),(2),(1),(4), (2), (3) 

chciałbym uzyskać wynik 4 (bo 4 jest najwyższa).

Rozwiązanie? Umieścić "różny" w pod zapytania tak:

SELECT  
    @result = @result 
     + CAST(Id AS VARCHAR(10)) + ',' 
FROM 
    (SELECT DISTINCT id 
    FROM @table) Q 

skutki: 1, 2, 3, 4,

+1

Właściwie jest interesujące. Nigdy się nad tym nie zastanawiałem, ale wydaje się, że jest to różnica w 'GROUP BY' vs' DISTINCT'. Plan wykonania zmienia kolejność, w jakiej oblicza wartość zmiennej ... – ZLK

+0

Dziękuję, wiem, że operator konkatenacji działa jako funkcja agregująca, ale dlaczego łączy operatora z Distinct act jako Max()? – Mohammadreza

+0

Twoje przepisanie wciąż zależy od zachowania, które zależy od planu wykonania i nie jest gwarantowane. Jedynym bezpiecznym sposobem jest użycie innej metody, takiej jak 'ścieżka xml'. –