【问题标题】:Dynamic SQL with variable number of table joins具有可变数量表连接的动态 SQL
【发布时间】:2012-11-22 10:53:03
【问题描述】:

我的表icdClm 是一个包含人员人口统计数据的表和另一个列出与该人相关的各种兴趣代码的表之间的连接表。我希望能够多次加入这些表格。由于此时简单起见,我对关系中涉及的其他表不感兴趣。我想要一个while loop 来帮助生成查询(如果有更好的方法,我愿意接受不同的实现。)

如果查询运行两次(两个派生表运行两次),以下是所需的输出。

select distinct x1.patid
from
(
select ic.patid
    from icdClm as ic
    where ic.icd like '123%'
) x1 inner join 
(
select ic.patid
    from icdClm as ic
    where ic.icd like '456%'
)x2 on x1.patid=x2.patid
inner join 
(
select ic.patid
    from icdClm as ic
    where ic.icd like '789%'

) x3 on x1.patid=x3.patid

请注意,派生表的别名每次都会增加 1。现在我的代码。这段代码不会产生错误,但我让它运行了 10 多分钟,还没有返回任何结果。最后,我想创建另一个依赖于这个的存储过程,它会询问您想要的派生表的数量,然后使用用户输入的参数填写where ic.icd like '123%',但首先要做的是:什么不适用于下面的查询?

declare 
@x int
,@y int
,@sql nvarchar(1000)

select 
@x=1
,@y=3
,@sql =
'select distinct x1.patid
from
(
select ic.patid
    from icdClm as ic
    where ic.icd like ''123%''
) x1'
while @x < @y
begin;
set @sql=@sql+ 
'inner join 
(
    select ic.pati
    from icdClm as ic
    where ic.icd like ''456%''
) x1 on x'+CAST(@y as CHAR(10))+'.patid=x1.patid'
set @y=@y+1
end;
print @sql

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql dynamic


    【解决方案1】:
    while @x < @y
    begin;
    
    set @y=@y+1
    end;
    

    @y 是递增的,所以这个循环要么永远不会执行(因为 y 小于 x),要么它将是一个无限循环*,因为 @y 总是大于 @x

    也许你的意思是@x=@x+1

    *你最终可能会得到整数溢出

    【讨论】:

    • 你是对的,应该是 @x 应该增加因为 duh!否则将是一个无限循环。现在查询实际运行了,我可以看到其他一些错误,但这是我的问题的症结所在。 gracias,高级弗里克斯。
    • :) 顺便说一句,我会在 join 子句中使用 AND 而不是内联视图 icdClm x1 INNER JOIN icdClm x2 on x1.patid=x2.patid and x1.icd like ''123%'' ... 但我不确定这会让事情变得更好
    • 这就是我最初考虑的方式,但是当我将其散列时,这种方式似乎更容易。我会做一些测试,无论哪个更快,我都会使用。
    • 另一种选择是以select patid from icdClm WHERE icd like ''123%'' Or icd like ''456%'' GROUP BY patid HAVING count(icd) = 2 的形式执行某些操作,然后您只需更改 WHERE 和 HAVING 子句
    • 这也是个好主意。 .我也得玩弄它。
    【解决方案2】:

    您似乎要执行多个术语的 and 条件。
    如果您使用 Intersect,则不需要唯一名称。
    我这样做,但我用 C# 构建它。
    抱歉缺少 SP 示例。

    select patid
        from icdClm 
        where icd like '123%'
    Intersect
    select patid
        from icdClm 
        where icd like '456%' 
    

    EXCEPT and INTERSECT (Transact-SQL)

    我发现 Intersect 很有效。
    连接超过 5 个时,查询优化器遇到了我所谓的防御性问题,并且对我的数据产生了较差的响应时间。
    Intersect 以蛮力方式一次执行一项,这可能对您的数据有利也可能不利。
    由于您喜欢的开头没有通配符,因此它可能使用索引。

    【讨论】:

    • hmm..这很有趣,我几乎从未使用过 intersect,而且我不知道您不必保留不同的别名。
    • 努力获得正确的别名(我仍在修补的东西)是我选择使用我想要的最终查询的精简版本的原因。我会看看它如何处理我的数据,但无论如何,这是一个很好的小消息,可以放在我的后口袋里。
    猜你喜欢
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2012-01-13
    • 2015-05-14
    相关资源
    最近更新 更多