gpt4 book ai didi

sql - 如何根据 SQL Server 2005 中的条件返回值集?

转载 作者:行者123 更新时间:2023-12-01 04:03:30 24 4
gpt4 key购买 nike

我是 SQL Server 2005 存储过程的初学者。我似乎无法让它按预期工作。

我有一个 sp 从名为 annot 的表中获取参数 @caseid . @caseid分配给列 src_caseid 的值并且可以在表 ref_caseid 中有多个引用( annot )或没有引用.我想设置一个条件并根据列设置适当的shepardsflag court来自表 case我是用 INNER JOIN 做的。

基本上是这样的场景:

  • annot - ref_caseid, src_caseid, annotation
  • case - caseid, court

  • 来自 ref_caseid = caseid 上的 INNER JOIN 的结果集示例像这样:
    ref_caseid   src_caseid   annotation    court
    17334 17338 Refd high court
    17600 17338 Foll federal court
    18271 17338 Foll federal court
    43220 17338 Not Foll supreme court

    设置条件:

    从记录集中,如果 federal court存在,它应该只需要行 federal court .如果没有 federal court被发现,那么它将处理具有其他法院值(value)的其他案件。

    为此,我为 federal court 设置了一个计数器。计数。但似乎 SQL 只读取最后一行并设置 @courtFC基于它的值(value)。我试过 order by但似乎效果不佳。

    从上面的示例中,案例 17338 的最终 shepardsflag 值应为 = 3(Foll),因为它应仅采用“联邦法院”行并忽略其余行。

    但是当前的结果是 shepardsflag = 2 ;这是错误的

    我希望我解释得很好。

    有人可以帮助我正确的逻辑吗?我应该创建一个临时表吗?提前致谢。

    脚本:
    ALTER PROCEDURE [dbo].[spUpdateShepardsFlags] @caseid int = null AS
    begin
    declare @Shep int
    declare @ref_caseid int
    declare @court int
    declare @courtFC int
    declare @annot int

    if @caseid is not null
    begin
    select @court = b.court, @ref_caseid = a.ref_caseid, @annot = a.annotation
    from cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid
    where a.src_caseid = @caseid

    if @court is not null
    begin
    if @court = 'MYFC'
    set @courtFC = @courtFC + 1
    if @court <> 'MYFC'
    SET @courtFC = @courtFC + 0
    PRINT 'The @courtFC counter : ' + CAST(@courtFC AS CHAR)
    end

    if @court is not NULL
    begin
    if @courtfc > 0
    begin
    if exists(select a.ref_caseid, b.court, a.annotation, a.src_caseid from
    cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid)
    begin
    if exists(select src_caseid from cba_annot where (annotation like '%Refd%'
    or annotation like '%Comp%')
    and src_caseid = @caseid)
    set @Shep = 4

    if exists(select src_caseid from cba_annot where (annotation like '%Foll%'
    or annotation like '%Aff%')
    and src_caseid = @caseid)
    set @ShepFC = 3

    update cbm_case
    set shepardsflag = @shep
    where caseid=@caseid
    end
    end

    else -- if @courtFC = 0
    begin --new
    if exists(select a.ref_caseid, b.court, a.annotation, a.src_caseid from
    cba_annot a inner join cbm_case b on a.ref_caseid = b.caseid)
    begin
    if exists(select src_caseid from cba_annot where (annotation like '%Refd%'
    or annotation like '%Comp%')
    and src_caseid = @caseid)
    set @Shep = 4

    if exists(select src_caseid from cba_annot where (annotation like '%Foll%'
    or annotation like '%Aff%')
    and src_caseid = @caseid)
    set @Shep = 3

    if exists(select src_caseid from cba_annot where (annotation like '%Not Foll%'
    or annotation like '%Dist%')
    and src_caseid = @caseid)
    set @Shep = 2

    update cbm_case
    set shepardsflag = @shep
    where caseid=@caseid
    end

    end -- new
    end
    else --- if court is NULL -- case not referred by any other case
    update cbm_case
    set shepardsflag = 5
    where caseid=@caseid
    end

    else -- if caseid is null

    -- other condition

    最佳答案

    您对 SQL 的理解遇到了一些实际问题,我严重怀疑临时表是否相关。

    1) 变量被初始化为 null,但这似乎并没有显着地把你搞砸。 (@courtFC + 0 不会以您可能想的方式评估您。)

    2) 你做作业的方式取决于顺序,最后一个获胜,正如你注意到的那样。而不是说:

    select @court = b.court, ...

    你可以使用这个:
    select @courtFC = count(b.court) ... where b.court = 'federal court'

    看来您正在尝试编写一个循环,我认为这是您困惑的另一部分。 SQL 是关于集合的,一次对多行进行操作。

    3) 内部块中的所有 EXISTS 子查询都缺少相关 caseid 上的过滤器。

    您的方法实际上可能仅适用于这些更改。

    我这里的版本不是为了让事情复杂化,但我担心你会遇到麻烦。这是一个基于集合的解决方案,它确实是一种更自然的方法。
    if @caseid is not null /* short-circuit the update, but probably not necessary */
    update cbm_case
    set shepardsflag = coalesce(
    (
    select
    case
    max( /* highest precendence wins */
    case /* map annotations by precedence i.e. */
    /* if there are multiple annotations, */
    /* which one takes priority */
    when a.annotation in ('Refd', 'Comp') then 'P1'
    when a.annotation in ('Foll', 'Aff') then 'P2'
    when a.annotation in ('Not Foll', 'Dist') then 'P3'
    else cast(0/0 as char(2)) /* error, I think */
    end
    )
    when 'P1' then 4 /* translate back to shepardsflag */
    when 'P2' then 3
    when 'P3' then 2
    end
    from
    cba_annot as a inner join cbm_case as refcase
    on refcase.caseid = a.ref_caseid
    where
    a.src_caseid = cbm_case.caseid
    and (
    cbm_case.court <> 'federal court' /* all if src case not federal */
    or refcase.court = 'federal court' /* always get federal */
    )
    ),
    5
    )
    where caseid = @caseid;

    编辑 2
    忽略我在 3) 中的评论。再看一遍,我认为由于括号和换行符,我误读了 OP 的代码。

    编辑 3
    修复了第一行缺少 @ 字符导致的错误。

    关于sql - 如何根据 SQL Server 2005 中的条件返回值集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11325421/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com