【问题标题】:Merge data from two tables horizontally水平合并两个表中的数据
【发布时间】:2023-04-04 13:20:01
【问题描述】:

我有来自两个源表“T”和“S”的数据,如下所示

我想将两个表中的数据水平合并并显示结果如下

Result 中的列名固定在哪里

  • D1、D2、D3 是日期列,在合并表 T 和 S 中每个组“代码”的数据后显示最后 3 个最大值(TDATE)
  • TID1,TID2,TID3 是 ID 从表 T 中获取日期 D1、D2、D3
  • SID1,SID2,SID3 是表 S 中的 ID 日期 D1,D2,D3

我下面的查询正在返回结果

WITH L1 AS
(
SELECT NULL AS TID, SID, CODE, TDATE 
FROM (VALUES
('S1','A','2001-01-01'),
('S3','A','2001-01-03'),
('S5','B','2001-01-05')
) V(SID,CODE,TDATE)
UNION ALL
SELECT TID, NULL AS SID, CODE, TDATE 
FROM (VALUES

('T1','A','2001-01-01'),
('T2','A','2001-01-02'),
('T5','B','2001-01-05')
) V(TID,CODE,TDATE)
)
,L2 AS 
(
SELECT SID,TID,CODE,[TDATE],
DENSE_RANK () over (
         partition by CODE
         order by [TDATE] desc
       ) RNO
FROM L1
)
,L3 AS 
(
SELECT MAX(TID) AS TID,MAX(SID) AS SID,CODE,TDATE,MAX(RNO)AS RNO
FROM L2
GROUP BY CODE,TDATE,RNO
HAVING MAX(RNO)<=3
)
SELECT * FROM L3

现在,如果我将查询“Select * from L3”的最后一行替换为以下水平旋转结果的查询,我将得到正确的结果。

SELECT 
 R1.CODE
 ,R1.TID AS TID1,R2.TID AS TID2,R3.TID AS TID3
 ,R1.SID AS SID1,R2.SID AS SID2,R3.SID AS SID3
 ,R1.TDATE AS D1 , R2.TDATE AS D2 , R3.TDATE AS D3 
FROM L3 R1
LEFT OUTER JOIN L3 R2 ON R1.RNO+1=R2.RNO AND R1.CODE=R2.CODE
LEFT OUTER JOIN L3 R3 ON R1.RNO+2=R3.RNO AND R1.CODE=R3.CODE
where R1.RNO=1

问题是上面的查询非常慢,当我必须在表 T 和 S 中运行它时,它有数千条记录,最后 5 个日期在 D1、D2、D3、D4、D5 列中

有没有其他方法可以优化这个查询或可以快速运行的新查询?

我尝试在表 T & S 上添加索引,如下所示

  • T(TID) 和 S(SID) 上的主键
  • T(Code,TDATE) 上的索引
  • T(TDATE) 上的索引
  • S 上的索引(代码,TDATE)
  • S(TDATE) 上的索引

表 T 和 S 中的总行数约为 50K,6 分钟后查询仍在运行

这是一个非常慢的实际查询的执行计划的链接 Execution Plan of actual slow query

【问题讨论】:

  • 实际执行计划是查找性能信息的好地方。请参阅paste the plan,了解在您的问题中包含执行计划的方法。
  • read this 然后edit 向我们提供更多信息,以便我们为您提供帮助。
  • 谢谢,@HOBO 我已经为运行缓慢的实际查询提供了执行计划的链接。
  • 嗨@O。琼斯 我在为查询中的所有表添加索引后更新了执行计划的问题和链接
  • 尝试将源表(TS)上的索引从 ( Code, TDate ) 更改为 ( Code, TDate desc ) 以满足您的 Dense_Rank 的需求。

标签: sql-server tsql pivot query-optimization


【解决方案1】:

我认为您在最后一次选择中进行连接会降低性能。

尝试使用枢轴操作怎么样?将选择替换为:

SELECT
    CODE
   ,Max(IIF(rno = 1, TID, NULL)) Tid1
   ,Max(IIF(rno = 2, TID, NULL)) Tid2
   ,Max(IIF(rno = 3, TID, NULL)) Tid3
   ,Max(IIF(rno = 1, SID, NULL)) Sid1
   ,Max(IIF(rno = 2, SID, NULL)) Sid2
   ,Max(IIF(rno = 3, SID, NULL)) Sid3
   ,Max(IIF(rno = 1, Tdate, NULL)) D1
   ,Max(IIF(rno = 2, Tdate, NULL)) D2
   ,Max(IIF(rno = 3, Tdate, NULL)) D3
FROM L3
GROUP BY Code

【讨论】:

    猜你喜欢
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    相关资源
    最近更新 更多