这个查询目前的功能我想要它的工作方式,但我的善良似乎是一个巨大的错误。它基本上是3个查询连接在一起并排序。我一遍又一遍地使用相同的逻辑,我希望有更好的方法来写这样的东西?
有没有办法不反复使用相同的选择逻辑?我可以以某种方式消除必须连接3次?
select z1.description, z0.* from (
select
p0.Id,
p0.[NetworkCompliant],
p0.[NetworkNonCompliant],
p0.[PercentageNetworkCompliant],
p0.[PercentageNetworkNonCompliant],
p1.[USNNetworkCompliant],
p1.[USNNetworkNonCompliant],
p1.[USNPercentageNetworkCompliant],
p1.[USNPercentageNetworkNonCompliant],
p2.[USMCNetworkCompliant],
p2.[USMCNetworkNonCompliant],
p2.[USMCPercentageNetworkCompliant],
p2.[USMCPercentageNetworkNonCompliant]
from (
select
t1.id as [Id],
SUM(case when t0.compliant = 1 then 1 else 0 end) as [NetworkCompliant],
SUM(case when t0.compliant = 0 then 1 else 0 end) as [NetworkNonCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 1 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [PercentageNetworkCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 0 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [PercentageNetworkNonCompliant]
from lineitemsmap as t0
inner join lineitems as t1 on t1.id = t0.lineitemid
inner join art_blob as t2 on t2.art_blob_id = t0.blobid
inner join art_asset as t3 on t3.art_asset_id = t2.art_asset_id and t3.decommissioned = 0
inner join net_ou as t4 on t4.NET_OUID = t3.NET_OUID
left outer join lineitemexceptions as t5 on t5.assetid = t3.art_asset_id and t5.lineitemid = t1.id
where t5.AssetId is null
group by t1.id
) as p0
left outer join (
select
t1.id as [Id],
SUM(case when t0.compliant = 1 then 1 else 0 end) as [USNNetworkCompliant],
SUM(case when t0.compliant = 0 then 1 else 0 end) as [USNNetworkNonCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 1 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USNPercentageNetworkCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 0 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USNPercentageNetworkNonCompliant]
from lineitemsmap as t0
inner join lineitems as t1 on t1.id = t0.lineitemid
inner join art_blob as t2 on t2.art_blob_id = t0.blobid
inner join art_asset as t3 on t3.art_asset_id = t2.art_asset_id and t3.decommissioned = 0
inner join net_ou as t4 on t4.NET_OUID = t3.NET_OUID
left outer join lineitemexceptions as t5 on t5.assetid = t3.art_asset_id and t5.lineitemid = t1.id
where t4.NET_EnclaveID = 2 and t5.AssetId is null
group by t1.id
) as p1 on p1.Id = p0.id
left outer join
(
select
t1.id as [Id],
SUM(case when t0.compliant = 1 then 1 else 0 end) as [USMCNetworkCompliant],
SUM(case when t0.compliant = 0 then 1 else 0 end) as [USMCNetworkNonCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 1 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USMCPercentageNetworkCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 0 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USMCPercentageNetworkNonCompliant]
from lineitemsmap as t0
inner join lineitems as t1 on t1.id = t0.lineitemid
inner join art_blob as t2 on t2.art_blob_id = t0.blobid
inner join art_asset as t3 on t3.art_asset_id = t2.art_asset_id and t3.decommissioned = 0
inner join net_ou as t4 on t4.NET_OUID = t3.NET_OUID
left outer join lineitemexceptions as t5 on t5.assetid = t3.art_asset_id and t5.lineitemid = t1.id
where t4.NET_EnclaveID = 1 and t5.AssetId is null
group by t1.id
) as p2 on p2.Id = p0.Id
) as z0
inner join lineitems as z1 on z1.id = z0.id
order by z0.id
答案 0 :(得分:1)
我认为这对于重复部件使用CTE是一个不错的选择。
您将不得不将NET_EnclaveID
和AssetId
添加到GroupBy
,并在查询中使用CTE进行过滤。如下所示:
WITH CTE AS
(
select
t4.NET_EnclaveID,
t5.AssetId
t1.id as [Id],
SUM(case when t0.compliant = 1 then 1 else 0 end) as [USNNetworkCompliant],
SUM(case when t0.compliant = 0 then 1 else 0 end) as [USNNetworkNonCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 1 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USNPercentageNetworkCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 0 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
end as [USNPercentageNetworkNonCompliant]
from lineitemsmap as t0
inner join lineitems as t1 on t1.id = t0.lineitemid
inner join art_blob as t2 on t2.art_blob_id = t0.blobid
inner join art_asset as t3 on t3.art_asset_id = t2.art_asset_id and t3.decommissioned = 0
inner join net_ou as t4 on t4.NET_OUID = t3.NET_OUID
left outer join lineitemexceptions as t5 on t5.assetid = t3.art_asset_id and t5.lineitemid = t1.id
group by
t1.id,
t4.NET_EnclaveID,
t5.AssetId
)
select z1.description, z0.* from (
select
p0.Id,
p0.[NetworkCompliant],
p0.[NetworkNonCompliant],
p0.[PercentageNetworkCompliant],
p0.[PercentageNetworkNonCompliant],
p1.[USNNetworkCompliant],
p1.[USNNetworkNonCompliant],
p1.[USNPercentageNetworkCompliant],
p1.[USNPercentageNetworkNonCompliant],
p2.[USMCNetworkCompliant],
p2.[USMCNetworkNonCompliant],
p2.[USMCPercentageNetworkCompliant],
p2.[USMCPercentageNetworkNonCompliant]
from (
select *
FROM CTE
where CTE.AssetId is null
) as p0
left outer join (
select *
FROM CTE
where CTE.NET_EnclaveID = 2 and CTE.AssetId is null
) as p1 on p1.Id = p0.id
left outer join
(
select *
FROM CTE
where CTE.NET_EnclaveID = 1 and CTE.AssetId is null
) as p2 on p2.Id = p0.Id
) as z0
inner join lineitems as z1 on z1.id = z0.id
order by z0.id
答案 1 :(得分:0)
我试图将那个长查询分成几部分。有一个长SELECT
重复三次(唯一的区别是重命名的列)。:
SELECT
t1.id as [Id],
SUM(case when t0.compliant = 1 then 1 else 0 end) as [USMCNetworkCompliant],
SUM(case when t0.compliant = 0 then 1 else 0 end) as [USMCNetworkNonCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 1 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
END as [USMCPercentageNetworkCompliant],
CASE WHEN SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) = 0 THEN
NULL
ELSE
convert(decimal(10,2), SUM(case when t0.compliant = 0 then 1 else 0 end) /
cast(SUM(case when t0.compliant = 0 then 1 else 0 end) + SUM(case when t0.compliant = 1 then 1 else 0 end) as float) * 100)
END as [USMCPercentageNetworkNonCompliant]
from lineitemsmap as t0
inner join lineitems as t1 on t1.id = t0.lineitemid
inner join art_blob as t2 on t2.art_blob_id = t0.blobid
inner join art_asset as t3 on t3.art_asset_id = t2.art_asset_id and t3.decommissioned = 0
inner join net_ou as t4 on t4.NET_OUID = t3.NET_OUID
left outer join lineitemexceptions as t5 on t5.assetid = t3.art_asset_id and t5.lineitemid = t1.id
我从现在开始将这个创作命名为YOUR_BIG_SELECT
。可能有一些优化可以在这里完成。如果不出意外,那些CASE陈述看起来很丑陋。然后将上面的SELECT放入一个大包装查询 - 我已将p0,p1和p2重命名为network
,usn
和usm
以提高可读性。
select z1.description, z0.* from (
select
network.Id,
network.somecolumns,
usn.somecolumns,
usm.somecolumns,
from ( YOUR_BIG_SELECT where t5.AssetId is null group by t1.id) as network
left outer join ( YOUR_BIG_SELECT where t4.NET_EnclaveID = 2 and t5.AssetId is null group by t1.id) as usn on usn.Id = network.id
left outer join ( YOUR_BIG_SELECT where t4.NET_EnclaveID = 1 and t5.AssetId is null group by t1.id) as usm on usm.Id = network.Id
) as z0
inner join lineitems as z1 on z1.id = z0.id
order by z0.id
加入lineitems
似乎没必要。 network.Id
来自lineitems.id
(内部联接为YOUR_BIG_SELECT中的t1)。因此,您只需将t1.description
添加到YOUR_BIG_SELECT,然后将您的查询改为:
select
network.Id,
network.description
network.somecolumns,
usn.somecolumns,
usm.somecolumns,
from ( YOUR_BIG_SELECT where t5.AssetId is null group by t1.id) as network
left outer join ( YOUR_BIG_SELECT where t4.NET_EnclaveID = 2 and t5.AssetId is null group by t1.id) as usn on usn.Id = network.id
left outer join ( YOUR_BIG_SELECT where t4.NET_EnclaveID = 1 and t5.AssetId is null group by t1.id) as usm on usm.Id = network.Id
order by network.id
我会看到摆脱这些子查询的机会,但这个解决方案不会更漂亮,所以我没有看到一点。
这就是我到目前为止所提出的。
答案 2 :(得分:0)
我已修改并希望简化您的要求。您可能需要重命名结果列,但这里有......
是的,您的查询基础几乎相同,但Enclave标志除外。第一个查询获取所有条目作为所有网络合规/不合规总计和百分比的基线。然后,对于USN应用与Enclave flag = 2完全相同的查询,对于USMC应用flag = 1。
所以我所做的是一个简单的查询来获取每一行,并且它的相应标志是“我不关心”(其中没有考虑标志),而Enclave标志分别为1或2。
因此,这给了我在Compliant或NonCompliant中的值为1或0的所有行,以及另外一组标志,以指示它基于Enclave 1或2。
现在,首先,我采用这个PQ(PreQuery)或原始的单独行并根据ID应用聚合,并获得Compliant,NonCompliant和相应的Compliant的总和,或者不用于飞地1和飞地2 ...现在都是汇总到每个ID级别。
现在,我将所有的SUMs()与分类(包围或不包括标志)一起考虑在内。因为我可以说,现在简化了CASE WHEN NetworkCompliant + NetworkNonCompliant = 0然后null else ...
现在,在分区中,而不是强制转换为浮动,如果我只做1.0000 *(等等),我只是强迫浮动到分区的那一部分。
所以,我有3个“值集”值...符合,NonCompliant,%兼容,%不符合ALL,Enclave 1标志(后缀为1)和Enclave 2标志(后缀为2)。
希望这有意义,并会为你而战。与原始查询一样复杂,我确信你会发现我在这个答案中可能遇到的任何“oops”类型o错误,因为我显然没有生产(甚至样本)表格。
select
PreSum1.ID,
NetworkCompliant,
NetworkNonCompliant,
CASE WHEN PreSum1.NetworkCompliant + PreSum1.NetworkNonCompliant = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkCompliant / ( 1.0000 * PreSum1.NetworkCompliant + PreSum1.NetworkNonCompliant ) * 100 )
END as [PercentageNetworkCompliant],
CASE WHEN PreSum1.NetworkCompliant + PreSum1.NetworkNonCompliant = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkNonCompliant / ( 1.0000 * PreSum1.NetworkCompliant + PreSum1.NetworkNonCompliant ) * 100 )
END as [PercentageNetworkNonCompliant],
NetworkCompliant1,
NetworkNonCompliant1,
CASE WHEN PreSum1.NetworkCompliant1 + PreSum1.NetworkNonCompliant1 = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkCompliant1 / ( 1.0000 * PreSum1.NetworkCompliant1 + PreSum1.NetworkNonCompliant1 ) * 100 )
END as [USMCPercentageNetworkCompliant1],
CASE WHEN PreSum1.NetworkCompliant1 + PreSum1.NetworkNonCompliant1 = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkNonCompliant1 / ( 1.0000 * PreSum1.NetworkCompliant1 + PreSum1.NetworkNonCompliant1 ) * 100 )
END as [USMCPercentageNetworkNonCompliant1],
NetworkCompliant2,
NetworkNonCompliant2,
CASE WHEN PreSum1.NetworkCompliant2 + PreSum1.NetworkNonCompliant2 = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkCompliant2 / ( 1.0000 * PreSum1.NetworkCompliant2 + PreSum1.NetworkNonCompliant2 ) * 100 )
END as [USNPercentageNetworkCompliant2],
CASE WHEN PreSum1.NetworkCompliant2 + PreSum1.NetworkNonCompliant2 = 0
THEN null
ELSE convert( decimal(10,2),
( PreSum1.NetworkNonCompliant2 / ( 1.0000 * PreSum1.NetworkCompliant2 + PreSum1.NetworkNonCompliant2 ) * 100 )
END as [USNPercentageNetworkNonCompliant2]
from
( SELECT
PQ1.ID,
SUM( NetworkCompliant ) NetworkCompliant,
SUM( NetworkNonCompliant ) NetworkNonCompliant
SUM( NetworkCompliant * EnclaveFlag1 ) NetworkCompliant1,
SUM( NetworkNonCompliant * EnclaveFlag1 ) NetworkNonCompliant1,
SUM( NetworkCompliant * EnclaveFlag2 ) NetworkCompliant2,
SUM( NetworkNonCompliant * EnclaveFlag2 ) NetworkNonCompliant2
from
( select
t0.lineitemid as [Id],
case when t0.compliant = 1 then 1 else 0 end as NetworkCompliant,
case when t0.compliant = 0 then 1 else 0 end as NetworkNonCompliant,
CASE when t4.NET_EnclaveID = 2 then 1 else 0 end as EnclaveFlag1,
CASE when t4.NET_EnclaveID = 2 then 1 else 0 end as EnclaveFlag2
from
lineitemsmap as t0
inner join lineitems as t1
on t0.lineitemid = t1.id
inner join art_blob as t2
on t0.blobid = t2.art_blob_id
inner join art_asset as t3
on t2.art_asset_id = t3.art_asset_id
and t3.decommissioned = 0
inner join net_ou as t4
on t3.NET_OUID = t4.NET_OUID
left outer join lineitemexceptions as t5
on t1.id = t5.lineitemid
and t3.art_asset_id = t5.assetid
where
t5.AssetId is null
group by
t0.lineitemid ) as PQ1
group by
PQ1.ID ) as PreSum1