我正在尝试改进的代码如下所示(简单示例):
SELECT DISTINCT a.col_a
,COALESCE(b1.col_c, b2.col_c, b3.col_c)
FROM tab_a a
LEFT JOIN tab_b b1
ON a.col_a = b1.col_a
AND b1.col_b = 'blabla1'
LEFT JOIN tab_b b2
ON a.col_a = b2.col_a
AND b2.col_b = 'blabla2'
LEFT JOIN tab_b b3
ON a.col_a = b3.col_a
AND b3.col_b = 'blabla3';
您可以使用以下脚本重新创建这些表
CREATE TABLE tab_a(col_a int)
CREATE TABLE tab_b(col_a INT, col_b VARCHAR(10), col_c INT)
INSERT INTO dbo.tab_a ( col_a ) VALUES ( 1 ), ( 2 ), ( 3 );
INSERT INTO dbo.tab_b ( col_a
,col_b
,col_c )
VALUES ( 1, 'blabla1', 1 )
,( 1, 'blabla2', 3 )
,( 1, 'blabla2', 5 )
,( 2, 'blabla2', NULL )
,( 2, 'blabla3', 5 );
如何将其更改为 1 join + 也许是窗口函数以及如何重写合并部分。只是为了解释一下,当前计划显示 3 个 tab_b 扫描,我想将其减少到 1 个。
此解决方案有 1 个 tab_b
scan
但添加sort
是因为您想b.col_c
在COALESCE
. 在上面的示例中,这order
对应于order
您的constants
injoin condition
对应于c
列的值。如果顺序应该不同,事情会更复杂,因为你应该编写自定义order by
子句。如果您希望或拥有这 3 个描述静态,您可以执行以下操作:
在临时表或变量表中插入值,但以列的形式 https://stackoverflow.com/questions/15745042/efficiently-convert-rows-to-columns-in-sql-server
在您的答案中编写脚本,但删除那些 3 LEFT JOIN,然后对临时表或变量表执行 CROSS JOIN
您还可以更改数据库模型以满足您最需要的内容。
为了提供帮助,请分享当前的数据库模型,以便我们进一步帮助您。您可以使用以下选项创建它:
1 按要求加入 ^^ 使用 IN (..) 编辑为更优雅的风格