【发布时间】:2021-06-10 07:49:22
【问题描述】:
我有这样的下表:
表 1:
我想通过使用表 2 中的以下范围在表 1 中创建几个段 (ScoreType)。
表 2:
我使用了简单的 case 语句并使用 table-2 中的值进行比较,因为我可以随时更新该表,而不是在查询中手动更改。
制作表格的代码:
--Table 1
Create table BandRange(
[ScoreType] Varchar(10)
,[MinDemand] INT
,[MaxDemand] INT
,[MinFrequency] INT
,[MaxFrequency] INT
,[ForWhat] Varchar(10)
);
Insert into BandRange
values
('ND-NF' , 0,0,0,0,'QtrYear')
,('ND-LF' , 0,0,0,5,'QtrYear')
,('ND-MF' , 0,0,6,15,'QtrYear')
,('ND-HF' , 0,0,16,99999,'QtrYear')
,('LD-NF' , 1,2,0,0,'QtrYear')
,('LD-LF' , 1,2,0,5,'QtrYear')
,('LD-MF' , 1,2,6,15,'QtrYear')
,('LD-HF' , 1,2,16,99999,'QtrYear')
,('MD-NF' , 3,5,0,0,'QtrYear')
,('MD-LF' , 3,5,0,5,'QtrYear')
,('MD-MF' , 3,5,6,15,'QtrYear')
,('MD-HF' , 3,5,16,99999,'QtrYear')
,('HD-NF' , 6,99999,0,0,'QtrYear')
,('HD-LF' , 6,99999,0,5,'QtrYear')
,('HD-MF' , 6,99999,6,15,'QtrYear')
,('HD-HF' , 6,99999,16,99999,'QtrYear');
--Table 2
create table QtrScores(MUID INT NOT NULL,Demand INT NOT NULL,Frequency INT NOT NULL);
Insert into QtrScores Values
(1,52,35),
(2,0,5),
(3,5,2),
(4,1,81),
(5,6,5),
(6,4,0),
(7,14,1)
我的代码:
--select * from QtrScores
--select * from BandRange
select MUID,Frequency,Demand,
case
--1st
when (Demand = (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-NF')
or Demand = ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-NF' )
) and (
Frequency = (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-NF')
or Frequency = (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-NF')
)
then 'ND-NF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-LF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-LF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-LF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-LF')
)
then 'ND-LF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-MF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-MF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-MF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-MF')
)
then 'ND-MF'
when (Demand <= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-HF')
and Demand >= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-HF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-HF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='ND-HF')
)
then 'ND-HF'
--2nd
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-NF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-NF' )
) and (
Frequency = (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-NF')
and Frequency = (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-NF')
)
then 'LD-NF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-LF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-LF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-LF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-LF')
)
then 'LD-LF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-MF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-MF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-MF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-MF')
)
then 'LD-MF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-HF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-HF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-HF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='LD-HF')
)
then 'LD-HF'
--3rd
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-NF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-NF' )
) and (
Frequency = (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-NF')
and Frequency = (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-NF')
)
then 'MD-NF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-LF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-LF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-LF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-LF')
)
then 'MD-LF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-MF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-MF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-MF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-MF')
)
then 'MD-MF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-HF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-HF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-HF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='MD-HF')
)
then 'MD-HF'
--4th
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-NF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-NF' )
) and (
Frequency = (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-NF')
and Frequency = (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-NF')
)
then 'HD-NF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-LF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-LF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-LF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-LF')
)
then 'HD-LF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-MF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-MF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-MF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-MF')
)
then 'HD-MF'
when (Demand >= (select MinDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-HF')
and Demand <= ( select MaxDemand from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-HF' )
) and (
Frequency >= (select MinFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-HF')
and Frequency <= (select MaxFrequency from BandRange(nolock) where ForWhat = 'QtrYear' and ScoreType ='HD-HF')
)
then 'HD-HF'
else 'NA'
End as ScoreType
from QtrScores(nolock)
我在 QtrYear 的表 1 中有大约 2500 万条记录,执行大约需要 1 小时 30 分钟。我对各种 QtrYear、HalfYear、Yearwise 有多个条件,这需要 10 多个小时才能执行。有更好的方法吗?
SQL Fiddle 的链接: http://sqlfiddle.com/#!18/60c62/5
【问题讨论】:
-
摆脱所有这些子查询将是朝着修复性能迈出的一大步。摆脱
NOLOCK提示是另一回事,对于如此长时间运行的查询,我不怀疑你最终会得到不正确的结果(你知道NOLOCK does that, right?). Note, as well, these areCASE` 表达式,而不是语句. T-SQL 不支持Case(Switch) 语句,这些语句会改变操作的逻辑流程,只支持CASE表达式。 -
您可能需要考虑为您的示例数据包含所需的输出。
-
你想要什么结果?问题不清楚。
标签: sql sql-server-2012 case query-optimization