用于动态查找表、DB2 或 SQL Server 的紧凑 CTE 语法

Posted

技术标签:

【中文标题】用于动态查找表、DB2 或 SQL Server 的紧凑 CTE 语法【英文标题】:Compact CTE syntax for on the fly lookup table, DB2 or SQL Server 【发布时间】:2021-06-10 21:48:32 【问题描述】:

我正在创建一个动态 SQL 查询并在 CTE 中动态构建一些查找表。我想出的语法非常冗长,我想知道是否有更紧凑的方式来表达这一点。查找表是在代码中创建的 CTE,并且可能因查询而异。希望这个例子说明清楚:

WITH lookuptable1 (code, desc)  
AS  
(  
    SELECT 18, 'Oakland' from Sysibm.sysdummy1 union 
    select 19, 'New York City' from Sysibm.sysdummy1 union 
    select 20, 'San Francisco' from  Sysibm.sysdummy1
)  
, lookuptable2 (code2, desc2) as
(  
    SELECT 18, 'CA' from Sysibm.sysdummy1 union 
    select 19, 'NY' from Sysibm.sysdummy1 union 
    select 20, 'AZ' from  Sysibm.sysdummy1 union 
    select 22, 'RI' from  Sysibm.sysdummy1  
)  
select user.userid,  code, desc, code2, desc2
from USER 
inner join lookuptable1 on user.city = lookuptable1.code
left outer join lookuptable2 on user.state = code2

【问题讨论】:

【参考方案1】:

对于 SQL Server,而不是

SELECT 18, 'Oakland' FROM Sysibm.sysdummy1 UNION
SELECT 19, 'New York City' FROM Sysibm.sysdummy1 UNION
SELECT 20, 'San Francisco' FROM Sysibm.sysdummy1

您可以使用VALUES 子句

SELECT id, Label
FROM (
VALUES
    (18, 'Oakland'),
    (19, 'New York City'),
    (20, 'San Francisco')
) as X (id, Label)

这里看起来并没有更紧凑,但会带来更多的价值。

如果使用UNION,您可以进一步改进它

SELECT 18, 'Oakland' UNION ALL
SELECT 19, 'New York City' UNION ALL
SELECT 20, 'San Francisco'

因此,如果您不使用表格,则无需从表格中进行选择。在联合时,您将使用union all 而不是union,因为您事先知道您需要所有行,而union 包含一个经常导致性能问题的重复数据删除阶段。

【讨论】:

你的答案很好,但是values 不是标准的 sql sintax...我不敢打赌它适用于 db2 以及 sql server @JaimeDrq 是的,但是,OP 说 OR 不是 BOTH - 所以也许它有帮助。 当然有帮助...我刚刚发表评论是因为Sysibm.sysdummy1 表类似于 DB2 中 Oracle 中的DUAL 表,所以我们在这里混合... 上述值适用于 3 种 Db2 产品中的 2 种:用于 IBM i 的 DB2 和用于 LUW 的 Db2。但在 DB2 for Z/OS 中没有。 感谢@MarkBarinstein,很高兴知道细节?。幸好我没打赌【参考方案2】:

Dale K 的回答对我有用,values 子句在两个数据库中都有效。我只是回答在这里发布完整的查询(正确的答案只显示部分语法,对于其他人我想发布完整的查询)

WITH  lookuptable1 (id, label) as
(select id, label 
from (
values 
    (0, 'Oakland'),
    (218, 'New York City'),
    (121, 'San Francisco')
 ) as X (id, Label))
, 
lookuptable2 (id, label) as
(select id, label 
from (  
 values
    ( 0, 'CA' ), 
    ( 97, 'NY' ),
    ( 316, 'AZ' ),
    ( 296, 'RI' )
) as Y (id,label)) 
select hji_id, name, lookuptable1.id, lookuptable1.label, lookuptable2.id, lookuptable2.label
from tt_hji 
inner join lookuptable1 on ry_id = lookuptable1.id
left outer join lookuptable2 on zone_id = lookuptable2.id

【讨论】:

以上是关于用于动态查找表、DB2 或 SQL Server 的紧凑 CTE 语法的主要内容,如果未能解决你的问题,请参考以下文章

表列表(在 DB2、SQL Server、Informix 和 Oracle 中)

用于存储动态二维数组的 SQL 设计和/或 PHP 类?

在 MS Access 或 SQL Server 中查找 2 个表之间的差异

SQL Server如何查找表名或列名中包含空格的表和列

如何把DB2的数据直接导入SQL server中

sqlserver和DB2的区别