【问题标题】:error with stored procedure logic存储过程逻辑错误
【发布时间】:2011-11-04 18:45:02
【问题描述】:

我正在尝试做类似的事情 How can I improve this SQL query?

但是,在逻辑上 本质上,我有一个 ID 列表,其中可能有多个与其关联的值,这些值是 Yes、No 或其他一些字符串。 对于 ID x,如果任何值是 Yes,x 应该是 Yes,如果它们都是 No,它应该是 No,如果它们包含除 yes 和 no 之外的任何其他值,则显示该值。我只想返回每个 ID 1 行,没有重复。

但在我的逻辑中,如果所有值都是yes,则显示yes,如果所有值都不是,则显示no,如果它是yes、no 或其他任何内容的混合,则显示混合

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 

【问题讨论】:

  • 由于某种原因,如果结果为 N,N,P 它仍然显示 N 或者如果它出现 Y,N 它会显示 Y。我希望 Y,Y 以 Y 和 N 的形式出现,N 以 N 形式出现,其他一切以 'M' 形式出现

标签: sql tsql stored-procedures sql-server-2000


【解决方案1】:
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

或者如果 any 存在而不是如果 allY

则返回 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

或者最终版本的字面意思是“如果它们包含除 yes 和 no 之外的任何其他值,则显示该值。”声明。

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

【讨论】:

  • @antisanity 14yn 所以 m 是必需的。
  • @antisanity - 啊,我明白你的意思了。问题本身有两个相互矛盾的规范。我假设其中一个是描述当前行为,另一个是期望的行为。我将添加一个执行粗体规范的版本,
  • @antisanity - 刚刚再次阅读了规范,我可以看到你从哪里来,但在 OP 明确要求之前我不会做任何进一步的编辑。
  • 改变了我的想法,但这是最后一次编辑,没有来自 OP 的任何额外输入!
【解决方案2】:

您可以使用max(),因为它是一个字符值。试一试:

注意:这里采用的逻辑是 Non-Y/N > Any Y > Only N

[编辑]重构和简化:

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

【讨论】:

  • 谢谢,但由于某种原因,我的更新语句不起作用,但我执行查询时的结果是。所以基本上我现在得到了正确的结果,但是我的更新查询给了我旧值
  • 啊,所以如果一条记录同时有 a y 和 a n 你将返回两行?
  • +1 顺便说一句,如果您对 CTE 和 SQL Server 2000 派生表有任何用处,您的答案中的先前评论仍然可用。
【解决方案3】:

另一种方法。我使用 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

【讨论】:

    猜你喜欢
    • 2011-05-28
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多