Избиране с предпочитание в SQL Server

Имам таблица в SQL Server 2000 с данни, подобни на следните:

ReferenceNumber    ReferenceValue
00001              Not assigned
00002              Not assigned
00002              ABCDE

в която всеки ReferenceNumber може да се появи няколко пъти в таблицата, или с ReferenceValue на „Не е присвоено“, или с истинска ReferenceValue.

Искам да изхвърля данните в изчистена таблица само с един ред на ReferenceNumber и истинска ReferenceValue, ако съществува, или „Не е присвоено“, ако няма истински ReferenceValue.

Виждам как да го направя с две заявки:

SELECT TOP 1 ReferenceNumber, ReferenceValue
INTO clean
FROM duplicates
WHERE ReferenceValue <> 'Not assigned'

INSERT INTO clean(ReferenceNumber, ReferenceValue)
SELECT TOP 1 ReferenceNumber, ReferenceValue
WHERE ReferenceValue = 'Not assigned' 
AND ReferenceNumber NOT IN (SELECT ReferenceNumber FROM clean)

но мисля, че трябва да има по-добър начин. Някакви идеи?


person taserian    schedule 22.10.2009    source източник


Отговори (2)


Нещо като това:

SELECT 
  ReferenceNumber
, ReferenceValue = ISNULL(MAX(NULLIF(ReferenceValue,'Not assigned')),'Not assigned')
INTO Table1_Clean
FROM Table1
GROUP BY
  ReferenceNumber

MAX() игнорира NULL, така че първо преобразувайте всичко, което не искате, в NULL, след това MAX(), след което преобразувайте NULL обратно във фиктивна стойност.

Едно преминаване, в линия, не може да стане много по-ефективно.

person Peter Radocchia    schedule 22.10.2009

За SQL SERVER 2000 това вероятно е най-лесно. Първа клауза = "реални" стойности, втора клауза, където не е намерена в първата клауза. И продължение на вашата идея.

SELECT d2.ReferenceNumber, d2.ReferenceValue
FROM duplicates d2
WHERE d2.ReferenceValue <> 'Not assigned'
UNION ALL
SELECT d1.ReferenceNumber, d1.ReferenceValue
FROM duplicates d1
WHERE NOT EXISTS (SELECT *
         FROM duplicates d2
         WHERE d2.ReferenceNumber = d1.ReferenceNumber AND
                 d2.ReferenceValue <> 'Not assigned')

Какви критерии обаче искате да свържете между "истинските" референтни стойности? или просто изберете един?

person gbn    schedule 22.10.2009
comment
За този конкретен проблем ReferenceNumber или ще има „Не е присвоено“, или ще има уникална ReferenceValue, така че няма проблем с връзките. - person taserian; 22.10.2009
comment
@taserian: премахна моя агрегат - person gbn; 22.10.2009
comment
Запазих агрегата, тъй като въпреки че RefNumber може да има една истинска RefValue, тази двойка RefNumber-RefValue може да се появи няколко пъти в таблицата. - person taserian; 22.10.2009
comment
Това са три четения и самостоятелно присъединяване, където ви трябва само едно четене и никакви присъединявания. - person Peter Radocchia; 23.10.2009
comment
@gbn: имахте ли предвид паралелно изпълнение, когато предложихте този метод? - person Peter Radocchia; 25.10.2009
comment
@Петър: не. Само за яснота. Разбирам вашето решение (гласувах за), но се надявам, че моето решение е по-ясно и очевидно. - person gbn; 25.10.2009
comment
@gbn: мислите ли, че това ще използва паралелни четения? Мисля, че може за четенията и присъединяванията, но имам сляпо място за паралелизъм и наистина не знам как да преценя относителната цена спрямо междинна макара. Remus посочи възможността тук: stackoverflow.com/questions/1618560/. Преди бях сигурен, сега не толкова. - person Peter Radocchia; 25.10.2009
comment
@Питър: по дяволите. Не знам. Спулирането обаче може да бъде скъпо и често едно от най-трудните неща за настройка. Предполагам, че зависи: индекси, брой редове, дали цената отговаря на паралелния праг и т.н. - person gbn; 25.10.2009
comment
@gbn: Оценявам дискусията. Благодаря! - person Peter Radocchia; 25.10.2009