MS-SQL / SQL-Server,JOIN加倍行

时间:2016-06-21 12:32:18

标签: sql sql-server join

起初,我是一个硬核新手!我现在尝试学习ms-sql一周,但我对以下内容感到困惑:

我有两个观点

v_helper_MONTH_DETAILS_ANBU 

ktr_kst | ktr_kst_bez | Warenwert | RKO     | Summe_ANBU | Inventarnummer | Bezeichnung1 | Bezeichnung 2 | Month 
-------------------------------------------------------------------------
8004    | Thing1      | 1217,00   | 1200,00 | 1200,00    | 160065         | bla_1        | bla_2         | 1
8774    | Thing2      | 99,56     | 100 ,00 | 100 ,00    | 150319         | bla_3        | bla_4         | 1
8774    | Thing2      | 99,56     | 99,56   | 99,56      | 150320         | bla_3        | bla_4         | 1

v_helper_MONTH_DETAILS_CAPEX

ktr_kst | ktr_kst_bez | Summe_CAPEX | Bereich | Beschreibung | Month 
-------------------------------------------------------------------------
8004    | Thing1      | 3000,00     | blub_1  | stuff        | 1
8004    | Thing1      | 1500,00     | blub_1  | stuffstuff   | 1

现在我需要一个查询,它给我这个输出:

ktr_kst | ktr_kst_bez | Warenwert | RKO     | Summe_ANBU | Inventarnummer | Bezeichnung1 | Bezeichnung 2 | Summe_CAPEX | Bereich | Beschreibung |Month 
    -------------------------------------------------------------------------
8004    | Thing1      | 1217,00   | 1200,00 | 1200,00    | 160065         | bla_1        | bla_2         | 3000,00     | blub_1  | stuff        | 1
8004    | Thing1      | 0         |       0 |       0    |      0         |              |               | 1500,00     | blub_1  | stuffstuff   | 1
8774    | Thing2      | 99,56     | 100,00  | 100,00     | 150319         | bla_3        | bla_4         | 0           |         |              | 1
8774    | Thing2      | 99,56     | 99,56   | 99,56      | 150320         | bla_3        | bla_4         | 0           |         |              | 1

所以基本上我需要所有v_helper_MONTH_DETAILS_ANBU以及v_helper_MONTH_DETAILS_CAPEX的所有内容与特定ktr_kst的{​​{1}}匹配

这是我的查询

Month (given by a variable)

这就是我得到的

DECLARE @Monat_var int
SET @Monat_var = 1

SELECT 
    @Monat_var AS Monat_var,
    CASE WHEN A.ktr_kst IS NULL THEN B.ktr_kst ELSE A.ktr_kst END AS ktr_kst,
    CASE WHEN A.ktr_kst_bez IS NULL THEN B.ktr_kst_bez ELSE A.ktr_kst_bez END AS ktr_kst_bez,
    CASE WHEN A.Warenwert IS NULL THEN 0 ELSE A.Warenwert END AS Warenwert,
    CASE WHEN A.RKO IS NULL THEN 0 ELSE A.RKO END AS RKO,
    CASE WHEN A.Summe_ANBU IS NULL THEN 0 ELSE A.Summe_ANBU END AS Summe_ANBU,
    CASE WHEN B.Summe_CAPEX IS NULL THEN 0 ELSE B.Summe_CAPEX END AS Summe_CAPEX,
    CASE WHEN A.Inventarnummer IS NULL THEN 0 ELSE A.Inventarnummer END AS Inventarnummer,
    CASE WHEN A.Bezeichnung1 IS NULL THEN '' ELSE A.Bezeichnung1 END AS Bezeichnung1,
    CASE WHEN A.Bezeichnung2 IS NULL THEN '' ELSE A.Bezeichnung2 END AS Bezeichnung2,
    CASE WHEN B.Bereich IS NULL THEN '' ELSE B.Bereich END AS Bereich,
    CASE WHEN B.Beschreibung IS NULL THEN '' ELSE B.Beschreibung END AS Beschreibung
FROM 
    v_helper_MONTH_DETAILS_ANBU AS A
    FULL JOIN v_helper_MONTH_DETAILS_CAPEX AS B on A.ktr_kst = B.ktr_kst AND @Monat_var = B.Month AND @Monat_var = A.Month
WHERE
    @Monat_var = A.Month
OR
    @Monat_var = B.Month
GROUP BY
    CASE WHEN A.ktr_kst IS NULL THEN B.ktr_kst ELSE A.ktr_kst END, CASE WHEN A.ktr_kst_bez IS NULL THEN B.ktr_kst_bez ELSE A.ktr_kst_bez END,
    A.Inventarnummer, A.Bezeichnung1, A.Bezeichnung2, B.Bereich, B.Beschreibung, A.Warenwert, A.RKO, A.Summe_ANBU, B.Summe_CAPEX

你可以看到,8004的第二个条目是错误的(或者第一个,无论哪一个)在列 Warenwert,RKO,Summe_ANBU,Inventarnummer,Bezeichnung1,Bezeichnung2 所以基本上一切从第一个视图,但加倍。但它应该给NULLS或定义的占位符。

同样,8004中的一个条目应该给出占位符而不是上面看到的,这两个来自哪一个无关紧要。

任何人都可以帮助一个血腥的菜鸟学习这个吗?我知道代码可能对你的专业人员来说很糟糕,但我会尝试"通过实践来学习"。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

您需要将 ROW_NUMBER PARTITION BY 一起使用,您可以使用 ISNULL 代替 CASE WHEN 。以下是完整查询:

DECLARE @Monat_var int
SET @Monat_var = 1

;WITH CTE_v_helper_MONTH_DETAILS_ANBU
AS
(
   SELECT *,
      ROW_NUMBER() OVER (PARTITION BY ktr_kst ORDER BY Month) RN
   FROM v_helper_MONTH_DETAILS_ANBU
),
CTE_v_helper_MONTH_DETAILS_CAPEX
AS
(
   SELECT *,
      ROW_NUMBER() OVER (PARTITION BY ktr_kst ORDER BY Month) RN
   FROM v_helper_MONTH_DETAILS_CAPEX
)

SELECT
    @Monat_var AS Monat_var,
    ISNULL(A.ktr_kst, B.ktr_kst) AS ktr_kst,
    ISNULL(A.ktr_kst_bez, B.ktr_kst_bez) AS ktr_kst_bez,
    ISNULL(A.Warenwert, 0) AS Warenwert,
    ISNULL(A.RKO, 0) AS RKO,
    ISNULL(A.Summe_ANBU, 0) AS Summe_ANBU,
    ISNULL(B.Summe_CAPEX, 0) AS Summe_CAPEX,
    ISNULL(A.Inventarnummer, 0) AS Inventarnummer,
    ISNULL(A.Bezeichnung1, '') AS Bezeichnung1,
    ISNULL(A.Bezeichnung2, '') AS Bezeichnung2,
    ISNULL(B.Bereich, '') AS Bereich,
    ISNULL(B.Beschreibung, '') AS Beschreibung
FROM CTE_v_helper_MONTH_DETAILS_ANBU A
FULL JOIN CTE_v_helper_MONTH_DETAILS_CAPEX B
  ON A.ktr_kst = B.ktr_kst AND A.RN = B.RN -- this is important
      AND @Monat_var = B.Month AND @Monat_var = A.Month
WHERE @Monat_var = A.Month OR @Monat_var = B.Month

<强>更新

您也可以在不使用; WITH (又称Common Table Expression)的情况下编写此查询。为此,您需要使用子查询来编写它。这是:

SELECT
    @Monat_var AS Monat_var,
    ISNULL(A.ktr_kst, B.ktr_kst) AS ktr_kst,
    ISNULL(A.ktr_kst_bez, B.ktr_kst_bez) AS ktr_kst_bez,
    ISNULL(A.Warenwert, 0) AS Warenwert,
    ISNULL(A.RKO, 0) AS RKO,
    ISNULL(A.Summe_ANBU, 0) AS Summe_ANBU,
    ISNULL(B.Summe_CAPEX, 0) AS Summe_CAPEX,
    ISNULL(A.Inventarnummer, 0) AS Inventarnummer,
    ISNULL(A.Bezeichnung1, '') AS Bezeichnung1,
    ISNULL(A.Bezeichnung2, '') AS Bezeichnung2,
    ISNULL(B.Bereich, '') AS Bereich,
    ISNULL(B.Beschreibung, '') AS Beschreibung
FROM 
(
   SELECT *,
     ROW_NUMBER() OVER (PARTITION BY ktr_kst ORDER BY Month) RN
   FROM v_helper_MONTH_DETAILS_ANBU
) A
FULL JOIN 
(
   SELECT *,
     ROW_NUMBER() OVER (PARTITION BY ktr_kst ORDER BY Month) RN
   FROM v_helper_MONTH_DETAILS_CAPEX
) B
ON A.ktr_kst = B.ktr_kst AND A.RN = B.RN -- this is important
  AND @Monat_var = B.Month AND @Monat_var = A.Month
WHERE @Monat_var = A.Month OR @Monat_var = B.Month