ошибка с логикой хранимой процедуры - PullRequest
2 голосов
/ 26 августа 2011

Я пытаюсь сделать что-то похожее на Как я могу улучшить этот SQL-запрос?

Впрочем, в этом есть логика По сути, у меня есть список идентификаторов, которые могут иметь несколько значений, связанных с ними, значения Да, Нет, или некоторые другие строки. Для идентификатора x, если любое из значений является Да, x должно быть Да, если все они Нет, это должно быть Нет, если они содержат какие-либо другие значения, кроме Да и Нет, отобразить это значение. Я хочу вернуть только 1 строку для каждого идентификатора, без дубликатов.

но в моей логике, если все значения равны yes, тогда отображать yes, если все значения no, затем отображать no, если это сочетание yes, no или чего-либо еще отображать mix

DECLARE @tempTable table ( ID int, Val varchar(1) )

    INSERT INTO @tempTable ( ID, Val ) VALUES ( 10, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 11, 'N')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 11, 'N')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 13, 'N')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 14, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 14, 'N')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 15, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 16, 'Y')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 17, 'F')
    INSERT INTO @tempTable ( ID, Val ) VALUES ( 18, 'P')


    SELECT DISTINCT t.ID, COALESCE(t2.Val, t3.Val, t4.Val)
    FROM @tempTable t
    LEFT JOIN
    (
        SELECT ID, Val
        FROM @tempTable
        WHERE Val = 'Y'
    ) t2 ON t.ID = t2.ID
    LEFT JOIN
    (
        SELECT 
        ID, Val FROM @tempTable
        WHERE Val = 'N'
    ) t3 ON t.ID = t3.ID
    LEFT JOIN
    (
        SELECT ID, Val
        FROM @tempTable
        WHERE Val <> 'Y' AND Val <> 'N'
    ) t4 ON t.ID = t4.ID

Update dbo.households
SET dbo.households.code = #TempTable.code
FROM #TempTable
WHERE dbo.households.id = #TempTable.id 

Ответы [ 3 ]

5 голосов
/ 26 августа 2011
SELECT  ID ,
        CASE WHEN MAX(Val) = MIN(Val)
                  AND MAX(Val) IN ( 'N', 'Y' ) THEN MAX(Val)
             ELSE 'M'
        END
FROM    @tempTable
GROUP BY ID

Или версия, которая возвращает Y, если любой существует, а не если все равны Y

SELECT  ID ,
        ISNULL(MAX(CASE WHEN Val = 'Y' THEN 'Y' END), 
               CASE WHEN MAX(Val) = MIN(Val) THEN MAX(Val)
                              ELSE 'M'
                         END)
FROM    @tempTable
GROUP BY ID

Или окончательная версия, которая принимает буквально «если они содержат какие-либо другие значения, кроме да и нет, отображают это значение». заявление.

SELECT  ID ,
        ISNULL(MAX(CASE WHEN Val = 'Y' THEN 'Y'END), 
               ISNULL(MAX(CASE WHEN Val NOT IN ( 'N', 'Y' ) THEN Val END), 
                      MAX(Val)))
FROM    @tempTable
GROUP BY ID
2 голосов
/ 26 августа 2011

Вы можете использовать max(), так как это значение символа.Дайте этому вихрь:

Примечание. Используемая здесь логика заключается в том, что Non-Y / N> Any Y> Only N

[Edit] Рефакторинг и упрощение:

select
 t.ID
,isnull(max(nyn.Val),max(yn.Val)) as Val
from @tempTable as t    
    left join @tempTable as nyn -- Non-Y/N value
    on nyn.ID = t.ID
    and nyn.Val not in ('Y','N')
    left join @tempTable as yn -- Y/N value
    on yn.ID = t.ID
    and yn.Val in ('Y','N')
group by t.ID

Дает следующие результаты:

ID  Val
10  Y
11  N
12  Y
13  N
14  Y
15  Y
16  Y
17  F
18  P
0 голосов
/ 26 августа 2011

Еще один способ сделать это. Я использую MAX () в случае возврата более одного значения, кроме Y и N

SELECT  
  ID,
  CASE  
    WHEN EXISTS(SELECT 1 FROM @tempTable tt WHERE t.ID = tt.ID AND tt.Val = 'Y')
             THEN 'Y'
    WHEN EXISTS(SELECT 1 FROM @tempTable tt WHERE t.ID = tt.ID AND tt.Val NOT IN ('Y','N')) 
             THEN (SELECT MAX(Val) FROM @tempTable  tt WHERE t.ID = tt.ID AND tt.Val NOT IN ('Y','N'))
    ELSE 'N'
  END           
FROM    @tempTable t
GROUP BY ID
...