微调MS SQL Server查询以分组结果联接两个表

时间:2018-11-18 10:08:15

标签: sql sql-server join

我想问你是否有一种有效的方法来编写查询以从下面提供的表中检索数据并仅显示我想要的列和值。我已经写了两个查询,但是第一个查询有点慢,第二个查询得到的列比我想要的多。

这是我的三个表:

enter image description here

enter image description here

enter image description here

这是我想要的输出: enter image description here

输出表应显示从1月到12月的每月值。 在实际数据库中,表A具有约40k行,表B具有20行,表C具有约100万行。 在下面,您可以看到我编写的查询的一部分,该查询会生成所需的输出,但是,当我为真正的数据库运行它时,它大约需要20-30秒:

  SELECT TableA.Id
    ,TableA.Title
    ,TableA.Description
    ,TableB.Title
    ,f1.[Value] as TableC_JanuaryValue
    ,f2.[Value] as TableC_FebruaryValue
    ....
    FROM <tablename>
INNER JOIN TableB ON TableB.Id = TableA.TableB_FK_Id
INNER JOIN TableC as f1 ON (f1.TableA_FK_Id = TableA.Id AND f1.[Year] = 2018 AND f1.[Month] = 1)
INNER JOIN TableC as f2 ON (f2.TableA_FK_Id = TableA.Id AND f2.[Year] = 2018 AND f2.[Month] = 2)
.....

我试图以不同的方式编写它并使之更快,但我设法将其缩短到2-3秒,但是输出并不是我想要的。 这是第二个查询:

  SELECT TableA.Id
    ,TableA.Title
    ,TableA.Description
    ,TableB.Title
    ,count(case when TableC.Value = 'V1' and TableC.[Month] = 1 then TableC.Id end) as JAN_IsV1
    ,count(case when TableC.Value = 'V2' and TableC.[Month] = 1 then TableC.Id end) as JAN_IsV2
    ,count(case when TableC.Value = 'V3' and TableC.[Month] = 1 then TableC.Id end) as JAN_IsV3
    ,count(case when TableC.Value = 'V1' and TableC.[Month] = 2 then TableC.Id end) as FEB_IsV1
    ,count(case when TableC.Value = 'V2' and TableC.[Month] = 2 then TableC.Id end) as FEB_IsV2
    ,count(case when TableC.Value = 'V3' and TableC.[Month] = 2 then TableC.Id end) as FEB_IsV3
    ....
    FROM <tablename>
INNER JOIN TableB ON TableB.Id = TableA.TableB_FK_Id
INNER JOIN TableC ON TableA.Id = TableC.TAbleA_FK_Id
where TableC.[Year] = 2018
group by TableA.Id, TableA.Title, TableA.Description, TableB.Title

这就是我得到的: enter image description here

我知道它非常接近我想要的结果,但是它并不完全相同:(

2 个答案:

答案 0 :(得分:2)

只需先将TableC旋转至 ,然后再将其加入其他应用。并使用MAX(CASE)代替COUNT(CASE)

SELECT
    TableA.Id
    ,TableA.Title
    ,TableA.Description
    ,TableB.Title
    ,TableC.*
FROM
    TableA
INNER JOIN
    TableB
        ON TableB.Id = TableA.TableB_FK_Id
INNER JOIN
(
    SELECT
        TableA_FK_Id,
        MAX(CASE WHEN [Month] = 1 THEN Value END) AS JAN,
        MAX(CASE WHEN [Month] = 2 THEN Value END) AS FEB, 
        MAX(CASE WHEN [Month] = 3 THEN Value END) AS MAR, 
        ...
    FROM
        TableC
    WHERE
        [YEAR] = 2018
    GROUP BY
        TableA_FK_Id
)
    TableC
        ON TableA.Id = TableC.TableA_FK_Id

答案 1 :(得分:-1)

 SELECT 
       tablea.Id AS TableA_Id,  
       tablea.Title AS TableA_Title, 
       tablea.Description AS TableA_Description,
       (SELECT tableb.Title FROM tableb WHERE tableb.Id = TableA.TableB_FK_Id) AS TableB_Id,
       (SELECT tablec.Value FROM tablec WHERE tablea.Id = TableC.TableA_FK_Id AND tablec.Month = 1) AS TableC_JanValue,
       (SELECT tablec.Value FROM tablec WHERE tablea.Id = TableC.TableA_FK_Id  AND tablec.Month = 2) AS TableC_FebValue
FROM tablea;

这个你也可以尝试.. !! :)