【问题标题】:Join on several tables and return data which could or could not exist in one table?加入多个表并返回一个表中可能存在或不存在的数据?
【发布时间】:2014-04-03 20:44:18
【问题描述】:

以下帖子与查询 SQL Server 2008 R2 (v10.50) 数据库有关。请忽略命名不佳的视图和表,因为它们没有遵循命名约定的最佳做法。

我有一个视图和三个表,我需要将它们连接起来并显示各种信息,以创建一个 .NET 前端界面。目标是捕获以下列:

  • AccountID
  • Account(姓名)
  • oYear(年)
  • Scenario
  • ProductID
  • f_m1 - f_m12(每个月的预测单位)
  • a_m1 - a_m12(每个月的实际单位)

对于给定的产品 ID、年份和场景。这将是最终的退货表,但将包含实际的销售数据。

请允许我详细说明视图和表格:

  • vw_account_tree 包含数据库中的所有帐户。最重要的是,我将在最终结果中引用AccountIDAccount 字段,并加入AccountID 字段。 WHERE 子句中的 atree.level3 IN() 限制器只是限制返回的帐户。

  • tbl_forecast_packworks 包含用户手动输入的预测数据,并包含 AccountIDProductIDUnitsScenariooMonthoYear 字段。这是 f_m1 - f_m12 的单位数据将被提取的地方。最重要的是,即使给定账户、产品、场景、月份和年份不存在条目,我也需要查询返回给定账户的数据(每个预测列中的 0)。

  • tbl_salesdata 包含已实现的销售数据。这是 a_m1 - a_m12 的单位数据将被提取的地方。最重要的是,我需要加入CustomerID 字段并引用UnitsGrossSales(单位),但它还包含oYearoMonthProductID

  • 最后,tbl_customers 只包含CustomerIDAccountID 之间的链接——这是它包含在查询中的唯一原因。

我已经构建了以下查询,但它没有准确返回实际单位 a_m1 - a_m12

SELECT atree.AccountID
,atree.Account
,ISNULL(forecast.oYear, 2014) oYear
,ISNULL(forecast.Scenario, 'CF') Scenario
,ISNULL(forecast.ProductID, '01227P') ProductID
,SUM(CASE WHEN forecast.omonth = 1 THEN forecast.Units ELSE 0 END) f_m1
,SUM(CASE WHEN forecast.omonth = 2 THEN forecast.Units ELSE 0 END) f_m2
,SUM(CASE WHEN forecast.omonth = 3 THEN forecast.Units ELSE 0 END) f_m3
,SUM(CASE WHEN forecast.omonth = 4 THEN forecast.Units ELSE 0 END) f_m4
,SUM(CASE WHEN forecast.omonth = 5 THEN forecast.Units ELSE 0 END) f_m5
,SUM(CASE WHEN forecast.omonth = 6 THEN forecast.Units ELSE 0 END) f_m6
,SUM(CASE WHEN forecast.omonth = 7 THEN forecast.Units ELSE 0 END) f_m7
,SUM(CASE WHEN forecast.omonth = 8 THEN forecast.Units ELSE 0 END) f_m8
,SUM(CASE WHEN forecast.omonth = 9 THEN forecast.Units ELSE 0 END) f_m9
,SUM(CASE WHEN forecast.omonth = 10 THEN forecast.Units ELSE 0 END) f_m10
,SUM(CASE WHEN forecast.omonth = 11 THEN forecast.Units ELSE 0 END) f_m11
,SUM(CASE WHEN forecast.omonth = 12 THEN forecast.Units ELSE 0 END) f_m12

,SUM(CASE WHEN sales.omonth = 1 THEN sales.UnitsGrossSales ELSE 0 END) a_m1
,SUM(CASE WHEN sales.omonth = 2 THEN sales.UnitsGrossSales ELSE 0 END) a_m2
,SUM(CASE WHEN sales.omonth = 3 THEN sales.UnitsGrossSales ELSE 0 END) a_m3
,SUM(CASE WHEN sales.omonth = 4 THEN sales.UnitsGrossSales ELSE 0 END) a_m4
,SUM(CASE WHEN sales.omonth = 5 THEN sales.UnitsGrossSales ELSE 0 END) a_m5
,SUM(CASE WHEN sales.omonth = 6 THEN sales.UnitsGrossSales ELSE 0 END) a_m6
,SUM(CASE WHEN sales.omonth = 7 THEN sales.UnitsGrossSales ELSE 0 END) a_m7
,SUM(CASE WHEN sales.omonth = 8 THEN sales.UnitsGrossSales ELSE 0 END) a_m8
,SUM(CASE WHEN sales.omonth = 9 THEN sales.UnitsGrossSales ELSE 0 END) a_m9
,SUM(CASE WHEN sales.omonth = 10 THEN sales.UnitsGrossSales ELSE 0 END) a_m10
,SUM(CASE WHEN sales.omonth = 11 THEN sales.UnitsGrossSales ELSE 0 END) a_m11
,SUM(CASE WHEN sales.omonth = 12 THEN sales.UnitsGrossSales ELSE 0 END) a_m12
FROM vw_account_tree atree
LEFT OUTER JOIN tbl_Packworks_Forecast forecast on forecast.AccountID = atree.AccountID
LEFT OUTER JOIN tbl_Customers cust on cust.AccountID = forecast.AccountID
LEFT OUTER JOIN tbl_salesdata sales ON sales.CustomerID = cust.CustomerID
WHERE (
    forecast.oYear = 2014
    OR forecast.oYear IS NULL
    )
AND (
    forecast.ProductID = '01227P'
    OR forecast.ProductID IS NULL
    )
AND (
    forecast.Scenario = 'CF'
    OR forecast.Scenario IS NULL
    )
AND atree.level3 IN ('ABC', 'BKR', 'CAT', 'CCO', 'DRM', 'DKS', 'DRT', 
'PJC', 'KAT', 'LCL', 'MCK', 'MET', 'PRO', 'SFY', 'SDM', 'SBN', 'TAR', 
'TMK', 'UPX', 'WMK', 'ZEL')
GROUP BY atree.AccountID
,atree.Account
,forecast.oYear
,forecast.Scenario
,forecast.ProductID
ORDER BY atree.Account

需要注意的是,ISNULL 的值和 oYearScenarioProductIDWHERE 子句中的值都是以编程方式提供的值,以便匹配用户的搜索条件.当用户进行更改并尝试保存预测时,我将这些列用作代码中的隐藏字段。

有人有什么建议吗?现在,实际的单位列正在返回不存在的数据,例如一个月有 3546 个单位,而 tbl_salesdata 表中该月实际有 0 个单位。我想我需要调整WHERE 子句,或者完全改变我制作查询的方式。如果您需要更多信息,请告诉我,谢谢!

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2


    【解决方案1】:

    我试图理解你的问题,我想我知道你想做什么,我认为这段代码会帮助你,但如果它真的对你有用,别忘了给我的答案打分hhhh:

    SELECT
             atree.AccountID
            ,atree.Account
    
            ,temp_tab.oYear
            ,temp_tab.Scenario
            ,temp_tab.ProductID
            ,temp_tab.f_m1
            ,temp_tab.f_m2
            ,temp_tab.f_m3
            ,temp_tab.f_m4
            ,temp_tab.f_m5
            ,temp_tab.f_m6
            ,temp_tab.f_m7
            ,temp_tab.f_m8
            ,temp_tab.f_m9
            ,temp_tab.f_m10
            ,temp_tab.f_m11
            ,temp_tab.f_m12
    
            ,temp_tab.a_m1
            ,temp_tab.a_m2
            ,temp_tab.a_m3
            ,temp_tab.a_m4
            ,temp_tab.a_m5
            ,temp_tab.a_m6
            ,temp_tab.a_m7
            ,temp_tab.a_m8
            ,temp_tab.a_m9
            ,temp_tab.a_m10
            ,temp_tab.a_m11
            ,temp_tab.a_m12
    
    FROM
        vw_account_tree atree
    LEFT OUTER JOIN
        (SELECT     
             COALESCE(forecast.AccountID, forecast.AccountID)   AS AccountID 
            ,COALESCE(forecast.oYear, forecast.oYear)           AS oYear
            ,COALESCE(forecast.Scenario, forecast.Scenario)     AS Scenario
            ,COALESCE(forecast.ProductID, forecast.ProductID)   AS ProductID
            ,forecast.f_m1
            ,forecast.f_m2
            ,forecast.f_m3
            ,forecast.f_m4
            ,forecast.f_m5
            ,forecast.f_m6
            ,forecast.f_m7
            ,forecast.f_m8
            ,forecast.f_m9
            ,forecast.f_m10
            ,forecast.f_m11
            ,forecast.f_m12
            ,sales.a_m1
            ,sales.a_m2
            ,sales.a_m3
            ,sales.a_m4
            ,sales.a_m5
            ,sales.a_m6
            ,sales.a_m7
            ,sales.a_m8
            ,sales.a_m9
            ,sales.a_m10
            ,sales.a_m11
            ,sales.a_m12
            FROM 
                (SELECT
                         AccountID
                        ,ISNULL(oYear,2014) oYear
                        ,ISNULL(Scenario,'CF') Scenario
                        ,ISNULL(ProductID,'01227P') ProductID
                        ,SUM(CASE WHEN omonth = 1 THEN Units ELSE 0 END) f_m1
                        ,SUM(CASE WHEN omonth = 2 THEN Units ELSE 0 END) f_m2
                        ,SUM(CASE WHEN omonth = 3 THEN Units ELSE 0 END) f_m3
                        ,SUM(CASE WHEN omonth = 4 THEN Units ELSE 0 END) f_m4
                        ,SUM(CASE WHEN omonth = 5 THEN Units ELSE 0 END) f_m5
                        ,SUM(CASE WHEN omonth = 6 THEN Units ELSE 0 END) f_m6
                        ,SUM(CASE WHEN omonth = 7 THEN Units ELSE 0 END) f_m7
                        ,SUM(CASE WHEN omonth = 8 THEN Units ELSE 0 END) f_m8
                        ,SUM(CASE WHEN omonth = 9 THEN Units ELSE 0 END) f_m9
                        ,SUM(CASE WHEN omonth = 10 THEN Units ELSE 0 END) f_m10
                        ,SUM(CASE WHEN omonth = 11 THEN Units ELSE 0 END) f_m11
                        ,SUM(CASE WHEN omonth = 12 THEN Units ELSE 0 END) f_m12
                FROM
                    tbl_Packworks_Forecast
                GROUP BY
                         AccountID
                        ,ISNULL(oYear,2014)
                        ,ISNULL(Scenario,'CF')
                        ,ISNULL(ProductID,'01227P') ) forecast
            FULL OUTER JOIN 
                (SELECT
                         cust.AccountID
                        ,ISNULL(oYear,2014) oYear
                        ,'CF' Scenario
                        ,ISNULL(ProductID,'01227P') ProductID
                        ,SUM(CASE WHEN omonth = 1 THEN UnitsGrossSales ELSE 0 END) a_m1
                        ,SUM(CASE WHEN omonth = 2 THEN UnitsGrossSales ELSE 0 END) a_m2
                        ,SUM(CASE WHEN omonth = 3 THEN UnitsGrossSales ELSE 0 END) a_m3
                        ,SUM(CASE WHEN omonth = 4 THEN UnitsGrossSales ELSE 0 END) a_m4
                        ,SUM(CASE WHEN omonth = 5 THEN UnitsGrossSales ELSE 0 END) a_m5
                        ,SUM(CASE WHEN omonth = 6 THEN UnitsGrossSales ELSE 0 END) a_m6
                        ,SUM(CASE WHEN omonth = 7 THEN UnitsGrossSales ELSE 0 END) a_m7
                        ,SUM(CASE WHEN omonth = 8 THEN UnitsGrossSales ELSE 0 END) a_m8
                        ,SUM(CASE WHEN omonth = 9 THEN UnitsGrossSales ELSE 0 END) a_m9
                        ,SUM(CASE WHEN omonth = 10 THEN UnitsGrossSales ELSE 0 END) a_m10
                        ,SUM(CASE WHEN omonth = 11 THEN UnitsGrossSales ELSE 0 END) a_m11
                        ,SUM(CASE WHEN omonth = 12 THEN UnitsGrossSales ELSE 0 END) a_m12
                FROM
                    tbl_salesdata sales
                LEFT OUTER JOIN
                    tbl_Customers cust
                        ON  sales.CustomerID = cust.CustomerID
                GROUP BY
                         cust.AccountID
                        ,ISNULL(oYear,2014)
                        ,ISNULL(ProductID,'01227P') ) sales
                    ON  sales.AccountID = forecast.AccountID
                    AND sales.oYear     = forecast.oYear
                    AND sales.Scenario  = forecast.Scenario
                    AND sales.ProductID = forecast.ProductID) AS temp_tab
            ON  temp_tab.AccountID = atree.AccountID            
    
    WHERE
            atree.level3 IN ('ABC', 'BKR', 'CAT', 'CCO', 'DRM', 'DKS', 'DRT', 
                            'PJC', 'KAT', 'LCL', 'MCK', 'MET', 'PRO', 'SFY', 'SDM', 'SBN', 'TAR', 
                            'TMK', 'UPX', 'WMK', 'ZEL')
    
    -- Filter
    AND     ISNULL(oYear,2014) = 2014
    AND     ISNULL(ProductID,'01227P') = '01227P'
    AND     ISNULL(Scenario,'CF') = 'CF'
    
    GROUP BY
             atree.AccountID
            ,atree.Account
            ,temp_tab.oYear
            ,temp_tab.Scenario
            ,temp_tab.ProductID
    ORDER BY
            atree.Account
    

    希望对你有帮助... 祝你好运!!

    【讨论】:

    • 是你要找的吗?
    • 你好优素福。我不太确定。不幸的是,tbl_salesdata 表中不存在 Scenario 列。从子查询和 GROUP BY 语句中删除该字段后,SQL Server 引发以下编译错误:Column 'temp_tab.f_m1' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
    猜你喜欢
    • 2012-11-10
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 2022-01-27
    • 2018-05-14
    • 1970-01-01
    相关资源
    最近更新 更多