自己加入巨大的 table

self join on huge table

我有以下table:

table1:

dateField   |   curStatus   |   prevStatus   |   statusChangeDate

2015-01-15  |      0        |      27        |   2015-01-15
2015-01-16  |      27       |      0         |   2015-01-16
2015-01-17  |      0        |      27        |   2015-01-17
2015-01-18  |      27       |      0         |   2015-01-18

我只想要那些记录,其中 curStatus0prevStatus最初是 272 天内 curStatus 0 到 27prevStatus 从 27 到 0.

table 包含大量数据。

我试过以下查询:

SELECT A.dateField, B.dateField, A.curStatus, B.curStatus, A.prevStatus, B.prevStatus 
FROM table1 A, table1 B
WHERE A.curStatus = 27 and A.prevStatus = 0
AND B.curStatus = 0 AND B.prevStatus = 27 AND CONVERT(DATE,B.statusChangeDate) <= CONVERT(DATE,DATEADD(d, -2, GETDATE()))

但它给了我笛卡尔积:

谁能帮我查询一下? 使用的数据库是 SQL 服务器

如果只有 2 种类型:0 和 27,并且您需要获取最近两天(从当前日期开始)的更新记录,您可以简单地使用下面的代码。但是如果你有更多类型,你将需要一些东西来识别行,例如主键。

create table st27 

(

datafield datetime,

curstatus int,

prevstatus int,

statuschangedate datetime

)

insert into st27 VALUES ('2015-01-15'  ,      0       ,     27,   '2015-01-15')
insert into st27 VALUES ('2015-01-16'  ,      27      ,      0         ,   '2015-01-16')

insert into st27 VALUES ('2015-01-17'  ,      0        ,      27        ,   '2015-01-17')

insert into st27 VALUES ('2015-01-18'  ,      27       ,      0         ,   '2015-01-18')


select *,datediff(d,statuschangedate, getdate())  from st27 where curstatus = 27 and prevstatus = 0  and datediff(d,statuschangedate, getdate()) <= 2

给出一条记录: 2015-01-18 00:00:00.000 27 0 2015-01-18 00:00:00.000 1

尝试交叉应用:

SELECT 
  A.dateField, B.dateField, A.curStatus, B.curStatus, A.prevStatus, B.prevStatus 
FROM 
  table1 A
CROSS APPLY
(
-- consider using
--  SELECT top 1 dateField, curStatus, prevStatus 
-- if you only want 1 row for each match
SELECT dateField, curStatus, prevStatus 
FROM table1
WHERE 
  dateField BETWEEN a.dateField and dateadd(d, 2, a.dateField) AND 
  curStatus = 0 and prevStatus = 27
-- in case you just want 1 row
-- ORDER BY datefield --(or whatever you want to order by)
) B
WHERE A.curStatus = 27 and A.prevStatus = 0