我在SQL Server 2014中有一个表,其中的示例数据如下所示。
WK_NUM | NET_SPRD_LCL 10 0 11 1500 12 3600 13 3800 14 4000
我正在尝试在工作中编写奖金结构,我需要在WK_NUM上进行分组。所以,如果我看到NET_SPRD_LCL> 3500表示两个连续的WK_NUMs WHERE WK_NUM< 27,我需要输出2000.在这个例子中,由于WK_NUM 12和13的NET_SPRD_LCL都大于3500,所以SQL应输出2000并退出。因此,它应该忽略WK_NUM 13和14也满足NET_SPRD_LCL>的条件的事实。 3500。
我很感激任何帮助。
答案 0 :(得分:2)
假设你的意思是连续的第1,2,3,4,5 ......等等而不是 1,3,5,8,12等
然后,如果您不需要知道它是哪一对连续记录:
Select case when exists
(Select * from table f
join table n
on n.Wk_Num = f.Wk_Num + 1
and n.NET_SPRD_LCL > 3500
and f.NET_SPRD_LCL > 3500
and n.Wk_Num < 27
then 2000 else null end
如果您确实需要识别这对记录,那么:
Select f.wk_Num firstWorkNbr, f.NET_SPRD_LCL firstNetSpread,
n.wk_Num nextWorkNbr, n.NET_SPRD_LCL nextNetSpread
from table f
join table n
on n.Wk_Num = f.Wk_Num + 1
and n.NET_SPRD_LCL > 3500
and f.NET_SPRD_LCL > 3500
and n.Wk_Num < 27
Where not exists
(Select * from table f0
join table n0
on n0.Wk_Num = f0.wk_Num + 1
and n0.WkNum < f.Wk_Num))
另一方面,如果连续只是增加,那么它会有点困难。您需要使用子查询来确定下一个连续记录...
Select case when exists
(Select * from table f
join table n
on n.Wk_Num = (Select Min(Wk_Num) from table
Where Wk_Num > f.Wk_Num)
and n.NET_SPRD_LCL > 3500
and f.NET_SPRD_LCL > 3500
and n.Wk_Num < 27
then 2000 else null end
如果您需要获取符合条件的特定第一对记录的数据(最后的2000是不必要的,因为如果没有合格的对,则不会返回任何内容。)
Select f.wk_Num firstWorkNbr, f.NET_SPRD_LCL firstNetSpread,
n.wk_Num nextWorkNbr, n.NET_SPRD_LCL nextNetSpread, 2000 outValue
from table f
join table n
on n.Wk_Num = (Select Min(Wk_Num) from table
Where Wk_Num > f.Wk_Num)
and n.NET_SPRD_LCL > 3500
and f.NET_SPRD_LCL > 3500
and n.Wk_Num < 27
Where not exists
(Select * from table f0
join table n0
on n0.Wk_Num = (Select Min(Wk_Num) from table
Where Wk_Num > f0.Wk_Num)
and n0.WkNum < f.Wk_Num))
答案 1 :(得分:1)
首先,当你说你想要你的查询输出&#39;并且&#39;退出&#39;,它让我觉得你正在接近t-sql作为一种程序性语言,但事实并非如此。好的t-sql查询几乎总是基于。
在任何情况下,在查询之前,让我添加有助于其他人处理数据以构建查询的内容:
DECLARE @t TABLE (WK_NUM INT, NET_SPRD_LCL INT);
INSERT INTO @t VALUES
(10, 0),
(11, 1500),
(12, 3600),
(13, 3800),
(14, 4000);
您说您正在使用SQL Server 2014,这意味着您可以使用相关的窗口功能。我正在使用的那个(LAG)将具有优于使用子查询的性能,如果你坚持使用它,可以通过使用带有ORDER BY的TOP(1)和适当的索引而不是整体使用MIN函数来大大改进数据集。使用少量数据,您不会注意到差异,但在实际业务系统中,这一点很明显。
调整后,在OP澄清后,在正确的行上提供2000奖金:
WITH cteTemp AS
(
SELECT WK_NUM
, thisValue = NET_SPRD_LCL
, lastValue = LAG(NET_SPRD_LCL) OVER(ORDER BY WK_NUM)
FROM @t
WHERE WK_NUM < 27
)
, cteBonusWeek AS
(
SELECT TOP (1)
WK_NUM
, bonus = 2000
FROM cteTemp
WHERE thisValue > 3500 AND lastValue > 3500
ORDER BY WK_NUM
)
SELECT t.WK_NUM
, t.NET_SPRD_LCL
, bonus = COALESCE(b.bonus, 0)
FROM @t AS t
LEFT JOIN cteBonusWeek AS b
ON b.WK_NUM = t.WK_NUM;