SQL Server 不使用JOIN查询两个表的结果

fnx2tebb  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(211)

我有2个数据表,都有一个日期时间列,但除了这个列没有其他匹配的列,因此不允许我做一个连接。
我已经尝试在MonthYear别名上进行连接,但这没有给我预期的结果,而且执行速度明显较慢,而单独进行连接是即时的。
但是,每个月都会有数据,因为我是按月计数和排序的,所以我认为连接可能不是必需的。我尝试过UNION,但是当我需要它在相邻列中时,它在额外的行中提供了结果(参见所需结果)。
表一:

SELECT
LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2) AS 'MonthYear',
COUNT(CASE WHEN responseType = 'positive' THEN 1 END) AS 'Positive',
COUNT(CASE WHEN responseType = 'negative' THEN 1 END) AS 'Negative'
FROM Database.dbo.Response
WHERE [date] BETWEEN '2022/09/01' AND '2022/12/01'
GROUP BY LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2)
ORDER BY MAX([date])

表1结果:

MonthYear      Positive     Negative
Sep-22         8738         6001
Oct-22         10120        4512
Nov-22         5621         5451

表二:

SELECT 
LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2) AS 'MonthYear',
COUNT(CASE WHEN Reason = 'Legacy Unsub' THEN 1 END) AS 'Unsub',
COUNT(CASE WHEN Reason = 'Complaint' THEN 1 END) AS 'Complaint'
FROM Database.dbo.Complaint
WHERE [date] BETWEEN '2022/09/01' AND '2022/12/01'
GROUP BY LEFT(DATENAME(MONTH, [date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2)
ORDER BY MAX([date])

表2结果:

MonthYear     Unsub    Complaint
Sep-22        541      5
Oct-22        171      0
Nov-22        459      12

我期望的结果:

MonthYear      Positive     Negative     Unsub     Complaint
Sep-22         8738         6001         541       5
Oct-22         10120        4512         171       0
Nov-22         5621         5451         459       12
xzlaal3s

xzlaal3s1#

我希望下面的代码能够给予预期的输出,并且性能不会比单独运行两个查询差很多(尽管这最终取决于返回的MonthYear的数量)。

WITH t1 AS
(
 SELECT
LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2) AS 'MonthYear',
 MAX([date]) AS 'SortOrder',
 COUNT(CASE WHEN responseType = 'positive' THEN 1 END) AS 'Positive',
 COUNT(CASE WHEN responseType = 'negative' THEN 1 END) AS 'Negative'
 FROM Database.dbo.Response
 WHERE [date] BETWEEN '2022/09/01' AND '2022/12/01'
 GROUP BY LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2)
),
t2 AS (
 SELECT 
 LEFT(DATENAME(MONTH,[date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2) AS 'MonthYear',
 COUNT(CASE WHEN Reason = 'Legacy Unsub' THEN 1 END) AS 'Unsub',
 COUNT(CASE WHEN Reason = 'Complaint' THEN 1 END) AS 'Complaint'
 FROM Database.dbo.Complaint
 WHERE [date] BETWEEN '2022/09/01' AND '2022/12/01'
 GROUP BY LEFT(DATENAME(MONTH, [date]),3) + '-' + RIGHT('00' + CAST(YEAR([date]) AS VARCHAR),2)
)
SELECT t1.MonthYear, t1.Positive, t1.Negative, t2.Unsub, t2.Complaint
FROM t1 FULL OUTER JOIN t2
  ON t1.MonthYear = t2.MonthYear
ORDER BY t1.SortOrder

这只是连接两个现有查询的结果(作为CTE)。我向第一个CTE添加了一个额外的SortOrder列(因为我们想按日期顺序排序,而不是字母顺序)。你说“每个月都会有数据”,所以也许在你的情况下一个INNER JOIN就足够了,但是FULL OUTER JOIN对于这种情况可能更安全(其中可能有一个表还没有另一个表所拥有的某个月的数据)。
虽然SQL不是过程化的,所以没有保证,但我希望SQL Server运行现有查询的时间与单独运行它们所需的时间大致相同,然后匹配,比如说,几千个MonthYear应该相对无关紧要。
如果这样做没有可接受的性能,我会考虑向两个表中添加一个计算列MonthYear,并为它建立索引。

相关问题