【问题标题】:Full Join on two temporary tables not returning all results SQL Server两个临时表上的完全联接不返回所有结果 SQL Server
【发布时间】:2011-10-24 22:29:46
【问题描述】:

更新:我已经包含了可以粘贴到 SSRS 中的完整代码,以显示结果。

我们报告大量以日期为中心的信息,并且必须从中生成报告。一些源数据没有及时更新,但为了确保报告整洁并且可以共享相同的日期列,我们有时会在查询上方使用 CTE 来生成过去 13 个月的列表。一台服务器仍在使用 SQL Server 2000,因此无法使用 CTE。我尝试填充两个临时表并使用完全连接,但它似乎将其视为内部连接。以下是代表性查询:

set DATEFORMAT ymd

IF object_id('tempdb..#EXAMPLE_SOURCE_DATA') is not null 
BEGIN    
  DROP TABLE #EXAMPLE_SOURCE_DATA
END

IF object_id('tempdb..#TEMP_STAGING') is not null 
BEGIN    
  DROP TABLE #TEMP_STAGING
END

IF object_id('tempdb..#TEMP_LAST13MONTHS') is not null 
BEGIN    
  DROP TABLE #TEMP_LAST13MONTHS
END

--This would normally be real data, but use a temporary for testing/bug fixing
CREATE TABLE #EXAMPLE_SOURCE_DATA(
   Date datetime,
   Actual float,
)

CREATE TABLE #TEMP_STAGING(
   Date datetime,
   Actual float,
)

CREATE TABLE #TEMP_LAST13MONTHS(
   Date13 datetime,
)

INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-06-27 12:34:56', 56.56)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-05-23 12:34:56', 45.45)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-04-11 12:34:56', 23.23)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-03-03 12:34:56', 12.12)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-02-01 12:34:56', 12.12)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-01-23 12:34:56', 45.45)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-04-11 12:34:56', 23.23)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-03-03 12:34:56', 12.12)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-02-01 12:34:56', 67.67)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-01-05 12:34:56', 56.56)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2011-02-01 12:34:56', 67.67)
INSERT INTO #EXAMPLE_SOURCE_DATA VALUES ('2010-12-05 12:34:56', 78.78)

-- Copy data to a temp table but 'flatten' the Date into beginning of month, to allow comparison and join.
INSERT INTO #TEMP_STAGING (Date, Actual)
SELECT 
  CAST(CAST(DATEPART(Year,Date) AS varchar) + '-' + CAST(DATEPART(Month,Date) AS varchar) + CAST('-01 00:00:00' as varchar) AS datetime) AS Date,
  Actual
FROM #EXAMPLE_SOURCE_DATA

--Insert rolling 13 months into a date table
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-1,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-2,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-3,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-4,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-5,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-6,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-7,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-8,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-9,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-10,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-11,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-12,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))
INSERT INTO #TEMP_LAST13MONTHS VALUES (DATEADD(MONTH,-13,DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()),0)))

-- DEBUG
--/*
SELECT * FROM #TEMP_LAST13MONTHS ORDER BY Date13 DESC
SELECT * FROM #EXAMPLE_SOURCE_DATA ORDER BY Date DESC
SELECT * FROM #TEMP_STAGING ORDER BY Date DESC
--*/

--This doesn't return values against 2011-07-01 or before 2010-12-01 ??? (Date this 

was written 2011-08)
SELECT
  Date,
  SUM(Actual)
FROM #TEMP_LAST13MONTHS
FULL OUTER JOIN #TEMP_STAGING ON #TEMP_LAST13MONTHS.Date13 = #TEMP_STAGING.Date
GROUP BY Date
ORDER BY Date DESC

【问题讨论】:

  • 我们可以得到一些具有预期结果的样本数据吗?您当前拥有的预期结果显示 4 列,但您的临时表中只有 2 列和 1 列,并且在最终选择中仅选择 2 列,因此很难理解为什么您希望看到 4 行 7/ 1/2011,空,空,空
  • 好的,我已经添加了临时表和最终输出的示例输出。这与 LEFT OUTER JOIN 相同,但对 RIGHT、FULL 等也是如此。
  • +1 提供可测试的脚本。
  • @Captian Bumble - 直到今天我才注意到你添加了一个可测试的脚本。为了将来参考,最好在您要求进一步信息的人的答案中添加评论。这样,系统就会通知该人。
  • @Caption Bumble - 我的答案已更改为包含您需要的查询(如果您仍然需要它)。

标签: sql-server join reporting-services temp-tables


【解决方案1】:

试试这个(我已经稍微更新了 sql):

SELECT  Date,
        LEFT(CAST(DATENAME(Month, Date) AS NVARCHAR), 3) + ' ' + CAST(YEAR(Date) AS NVARCHAR) AS MonthYear
FROM    [#TEMP_LAST13MONTHS]
        LEFT OUTER JOIN [#TEMP_STAGING]
            ON [#TEMP_LAST13MONTHS].Date13 = [#TEMP_STAGING].Date
WHERE   Date IS NULL OR (Date BETWEEN @StartOfMonthlyReporting AND @EndOfMonthlyReporting)
ORDER BY Date DESC

很抱歉,我不能比要求您尝试上述方法更有帮助,因为我在运行您的脚本时收到以下错误:

消息 208,级别 16,状态 1,第 26 行无效的对象名称“dDate”。

【讨论】:

    【解决方案2】:

    您有一个 where 子句明确#TEMP _STAGING 中选择date 列,从而有效地过滤掉#TEMP_LAST13MONTHS 中在#TEMP_STAGING 中没有对应行的每一行

    将 where 子句更改为

    (COALESCE(Date, Date13) BETWEEN @StartOfMonthlyReporting AND @EndOfMonthlyReporting)
    

    应该足够了(并且使用FULL OUTER JOIN

    编辑

    你可以使用这个

    SELECT  [Date]
            , SUM([Actual])
    FROM    (       
                SELECT  [Date] = COALESCE(#TEMP_STAGING.Date, #TEMP_LAST13MONTHS.Date13)
                        , [Actual] = COALESCE(Actual, 0)
                FROM    #TEMP_LAST13MONTHS 
                        FULL OUTER JOIN #TEMP_STAGING ON #TEMP_LAST13MONTHS.Date13 = #TEMP_STAGING.Date
            ) q
    GROUP BY 
            Date
    ORDER BY 
            Date DESC
    

    或者这个

    SELECT  [Date] = COALESCE(#TEMP_STAGING.Date, #TEMP_LAST13MONTHS.Date13)
            , [Actual] = SUM(COALESCE(Actual, 0))
    FROM    #TEMP_LAST13MONTHS 
            FULL OUTER JOIN #TEMP_STAGING ON #TEMP_LAST13MONTHS.Date13 = #TEMP_STAGING.Date
    GROUP BY
            COALESCE(#TEMP_STAGING.Date, #TEMP_LAST13MONTHS.Date13)
    ORDER BY
            1 DESC
    

    返回您需要的每一行。 (我的个人偏好是,虽然更长,第一个选项)

    【讨论】:

    • 添加 COALESCE 和 FULL OUTER JOIN 会增加五个结果,4 个用于日期 2010-07-01 和一个 NULL、NULL、NULL 一个?
    • 执行SELECT @EndOfMonthlyReporting会得到什么?
    • 起止如下:Jul 1 2010 12:00AM Aug 1 2011 12:00AM
    • 凹凸。这个还是不开心吗? ://
    • @Captain - 如果您要发布一些可运行的脚本来演示该问题,我会非常乐意查看它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2018-04-22
    • 2017-07-01
    • 2020-04-05
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多