如何检查下一个值是否接近 sql 中的上一个值
How to check if next value is close to previous value in sql
我有一个 table 列
ID int,
NUM int,
FK_POS int,
TRANS_DATE datetime
首先,我得到这个 table 的行,然后我想得到下一行的值(按 ID),然后我想检查下一行的 NUM,FK_POS TRANS_dATE 值与前一行的值相同..
例如我有;
"ID" "NUM" "FK_POS" "TRANS_DATE"
"1" "429" "2043" "2015-01-11 23:40:00.000"
我想检查第二行的 NUM、FK_POS 和 TRANS_DATE 值。
如果有这样一行;
"2" "429" "2043" "2015-01-11 23:40:00.000"
这就是我想要的;这可能吗?
是这样的吗?
SELECT *
FROM table a JOIN table b on b.id = a.id + 1
WHERE a.NUM = b.NUM AND etc...
您可以自己加入table:
SELECT ID, NUM, FK_POS, TRANS_DATE,
NextRowHasSameValues = CASE
WHEN t2.ID IS NOT NULL
AND t1.NUM = t2.NUM
AND t1.FK_POS = t2.FK_POS
AND t1.TRANS_DATE = t2.TRANS_DATE
THEN 'Yes' ELSE 'No' END
FROM dbo.TableName t1
LEFT OUTER JOIN dbo.TablName t2
ON t1.ID = t2.ID - 1
如果您使用的是 SQL Server 2012+,那么您可以使用 lead()
:
select t.*,
(case when num = lead(num) over (order by id) and
fk_pos = lead(fk_pos) over (order by id) and
trans_date = lead(trans_date) over (order by id)
then 1 else 0
end) as SameAsNext
from table t;
如果您使用的是早期版本,您可以使用 cross apply
做一些非常相似的事情:
select t.*,
(case when t.num = tnext.num and
t.fk_pos = tnext.fk_pos and
t.trans_date = tnext.rans_date
then 1 else 0
end) as SameAsNext
from table t cross apply
(select top 1 t2.*
from table t2
where t2.id > t.id
order by t2.id asc
) tnext
我能想到的第一种方法(可能有更好的方法)是使用 where 子句和 EXISTS
SELECT ID, NUM, FK_POS, TRANS_DATE
FROM tblTable pt
WHERE EXISTS(SELECT 1 FROM tblTable ct WHERE pt.NUM = ct.NUM AND pt.FK_POS = ct.FK_POS AND pt.TRANS_DATE = ct.TRANS_DATE AND pt.ID + 1 = ct.ID)
/*This is assuming your ID is an Identity field*/
如果不在乎是不是前一行,可以使用几个更好的方法:
第一个也是最好的方法是使用 GROUP BY
SELECT MIN(ID)/*or MAX(ID)*/, NUM, FK_POS, TRANS_DATE
FROM tblTable
GROUP BY NUM, FK_POS, TRANS_DATE
HAVING COUNT(*) > 1
或者,您可以将 DISTINCT 与子查询一起使用
SELECT ID, NUM, FK_POS, TRANS_DATE
FROM tblTable
WHERE ID NOT IN (SELECT DISTINCT NUM, FK_POS, TRANS_DATE FROM tblTable)
我有一个 table 列
ID int,
NUM int,
FK_POS int,
TRANS_DATE datetime
首先,我得到这个 table 的行,然后我想得到下一行的值(按 ID),然后我想检查下一行的 NUM,FK_POS TRANS_dATE 值与前一行的值相同..
例如我有;
"ID" "NUM" "FK_POS" "TRANS_DATE"
"1" "429" "2043" "2015-01-11 23:40:00.000"
我想检查第二行的 NUM、FK_POS 和 TRANS_DATE 值。
如果有这样一行;
"2" "429" "2043" "2015-01-11 23:40:00.000"
这就是我想要的;这可能吗?
是这样的吗?
SELECT *
FROM table a JOIN table b on b.id = a.id + 1
WHERE a.NUM = b.NUM AND etc...
您可以自己加入table:
SELECT ID, NUM, FK_POS, TRANS_DATE,
NextRowHasSameValues = CASE
WHEN t2.ID IS NOT NULL
AND t1.NUM = t2.NUM
AND t1.FK_POS = t2.FK_POS
AND t1.TRANS_DATE = t2.TRANS_DATE
THEN 'Yes' ELSE 'No' END
FROM dbo.TableName t1
LEFT OUTER JOIN dbo.TablName t2
ON t1.ID = t2.ID - 1
如果您使用的是 SQL Server 2012+,那么您可以使用 lead()
:
select t.*,
(case when num = lead(num) over (order by id) and
fk_pos = lead(fk_pos) over (order by id) and
trans_date = lead(trans_date) over (order by id)
then 1 else 0
end) as SameAsNext
from table t;
如果您使用的是早期版本,您可以使用 cross apply
做一些非常相似的事情:
select t.*,
(case when t.num = tnext.num and
t.fk_pos = tnext.fk_pos and
t.trans_date = tnext.rans_date
then 1 else 0
end) as SameAsNext
from table t cross apply
(select top 1 t2.*
from table t2
where t2.id > t.id
order by t2.id asc
) tnext
我能想到的第一种方法(可能有更好的方法)是使用 where 子句和 EXISTS
SELECT ID, NUM, FK_POS, TRANS_DATE
FROM tblTable pt
WHERE EXISTS(SELECT 1 FROM tblTable ct WHERE pt.NUM = ct.NUM AND pt.FK_POS = ct.FK_POS AND pt.TRANS_DATE = ct.TRANS_DATE AND pt.ID + 1 = ct.ID)
/*This is assuming your ID is an Identity field*/
如果不在乎是不是前一行,可以使用几个更好的方法:
第一个也是最好的方法是使用 GROUP BY
SELECT MIN(ID)/*or MAX(ID)*/, NUM, FK_POS, TRANS_DATE
FROM tblTable
GROUP BY NUM, FK_POS, TRANS_DATE
HAVING COUNT(*) > 1
或者,您可以将 DISTINCT 与子查询一起使用
SELECT ID, NUM, FK_POS, TRANS_DATE
FROM tblTable
WHERE ID NOT IN (SELECT DISTINCT NUM, FK_POS, TRANS_DATE FROM tblTable)