微调MS SQL server查询连接两个具有分组结果的表
我想问一下,是否有有效的方法来编写一个查询,从下面提供的表中检索数据,并只显示我想要的列和值。我已经写了两个查询,但是第一个查询有点慢,第二个查询得到的列比我想要的多 这是我的三张桌子: 这是我想要的输出: 输出表应显示从一月到十二月的月值。 在实际数据库中,表A约有40k行,表B约有20行,表C约有100万行。 下面您可以看到我编写的查询的一部分,它生成了所需的输出,但是当我为real DB运行它时,需要大约20-30秒:微调MS SQL server查询连接两个具有分组结果的表,sql,sql-server,join,Sql,Sql Server,Join,我想问一下,是否有有效的方法来编写一个查询,从下面提供的表中检索数据,并只显示我想要的列和值。我已经写了两个查询,但是第一个查询有点慢,第二个查询得到的列比我想要的多 这是我的三张桌子: 这是我想要的输出: 输出表应显示从一月到十二月的月值。 在实际数据库中,表A约有40k行,表B约有20行,表C约有100万行。 下面您可以看到我编写的查询的一部分,它生成了所需的输出,但是当我为real DB运行它时,需要大约20-30秒: SELECT TableA.Id ,TableA.
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)
.....
选择TableA.Id
,表a.标题
,表A.说明
,表b
,f1.[值]作为表C\u一月值
,f2。[值]作为表C_二月值
....
从…起
TableB.Id=TableA.TableB\u FK\u Id上的内部联接TableB
内部联接表C为f1 ON(f1.TableA\u FK\u Id=TableA.Id,f1.[Year]=2018,f1.[Month]=1)
内部联接表C为f2 ON(f2.TableA_FK_Id=TableA.Id,f2.[Year]=2018,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
选择TableA.Id
,表a.标题
,表A.说明
,表b
,计数(当TableC.Value='V1'和TableC.[Month]=1,然后TableC.Id结束时的情况)为JAN_IsV1
,计数(当TableC.Value='V2'和TableC.[Month]=1,然后TableC.Id结束时的情况)为JAN_IsV2
,计数(当TableC.Value='V3'和TableC.[Month]=1,然后TableC.Id结束时的情况)为JAN_IsV3
,计数(当table.Value='V1'和table.c.[Month]=2时,则table.Id结束)为2月1日
,计数(当TableC.Value='V2'和TableC.[Month]=2时,则TableC.Id结束)为2月2日
,计数(当TableC.Value='V3'和TableC.[Month]=2,然后TableC.Id结束时的情况)为FEB_IsV3
....
从…起
TableB.Id=TableA.TableB\u FK\u Id上的内部联接TableB
TableA.Id上的内部联接TableC=TableC.TableA\u FK\u Id
其中表C.【年份】=2018年
按TableA.Id、TableA.Title、TableA.Description、TableB.Title分组
下面是我得到的:
我知道它非常接近我想要的结果,但是它并不完全相同:(在将表C与其他表连接之前,只需在表C上旋转,并使用
MAX(CASE)
而不是COUNT(CASE)
这个你也可以试试。!!:)Matbailie,谢谢!我错过了那一个。它不仅有效,而且在一秒钟内有效!谢谢!:)
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
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;