sql-server – SQL Server 2005 T-SQL问题:在省略记录时需要帮助

美好的一天!

我在编写查询时需要帮助.我在下面的表中有记录.如果从先前的记录(new_state)重复后续记录’new_state并且在同一个记录中更改了记录,则条件将不会显示日期..

这里record_id 1已经通过ff状态:0-> 1-> 2-> 1-> 3-> 4->> 3在同一天…状态1变为状态2然后返回再次状态1(不显示id 2& 3)..与状态3相同(不显示id 5& 6)

id | record_id| date_changed | old_state | new_state |
1  | 1        | 2009-01-01   | 0         | 1         |
2  | 1        | 2009-01-01   | 1         | 2         | not displayed
3  | 1        | 2009-01-01   | 2         | 1         | not displayed
4  | 1        | 2009-01-01   | 1         | 3         |
5  | 1        | 2009-01-01   | 3         | 4         | not displayed
6  | 1        | 2009-01-01   | 4         | 3         | not displayed

所以结果只显示record_id = 1的2条记录.

id | record_id| date_changed | old_state | new_state |
1  | 1        | 2009-01-01   | 0         | 1         |
4  | 1        | 2009-01-01   | 1         | 3         |

这是表创建和数据的代码:

IF OBJECT_ID('TempDB..#table','U') IS NOT NULL
      DROP TABLE #table
CREATE TABLE #table
(
id INT identity primary key,
record_id INT,
date_changed DATETIME,
old_state INT,
new_state INT
)
INSERT INTO #table(record_id,date_changed,old_state,new_state)
    SELECT 1,'2009-01-01',0,1 UNION ALL --displayed
    SELECT 1,'2009-01-01',1,2 UNION ALL --not displayed
    SELECT 1,'2009-01-01',2,1 UNION ALL --not displayed
    SELECT 1,'2009-01-01',1,3 UNION ALL --displayed
    SELECT 1,'2009-01-01',3,4 UNION ALL --not displayed
    SELECT 1,'2009-01-01',4,3           --not displayed

INSERT INTO #table(record_id,date_changed,old_state,new_state)
    SELECT 3,'2009-01-01',0,1 UNION ALL --displayed
    SELECT 3,'2009-01-01',1,2 UNION ALL --not displayed
    SELECT 3,'2009-01-01',2,3 UNION ALL --not displayed
    SELECT 3,'2009-01-01',3,4 UNION ALL --not displayed
    SELECT 3,'2009-01-01',4,1           --not displayed

SELECT * FROM #table

我将不胜感激任何帮助..

谢谢

有关record_id = 3的清晰度,请参阅此表:

id | record_id| date_changed | old_state | new_state |
7  | 3        | 2009-01-01   | 0         | 1         |
8  | 3        | 2009-01-01   | 1         | 2         | not displayed
9  | 3        | 2009-01-01   | 2         | 3         | not displayed
10 | 3        | 2009-01-01   | 3         | 4         | not displayed
11 | 3        | 2009-01-01   | 4         | 1         | not displayed

当运行record_id = 3的查询时,表结果将是:

id | record_id| date_changed | old_state | new_state |
7  | 3        | 2009-01-01   | 0         | 1         |

谢谢!

更新(12/2/2009):

特殊情况

id | record_id| date_changed | old_state | new_state |
1  | 4        | 2009-01-01   | 0         | 1         | displayed
2  | 4        | 2009-01-01   | 1         | 2         | displayed
3  | 4        | 2009-01-01   | 2         | 3         | not displayed
4  | 4        | 2009-01-01   | 3         | 2         | not displayed
5  | 4        | 2009-01-01   | 2         | 3         | displayed
6  | 4        | 2009-01-01   | 3         | 4         | not displayed
7  | 4        | 2009-01-01   | 4         | 3         | not displayed

其中new_state 3出现在id 3,5和7 .. id 3将不会显示,因为它位于id 2和id 4之间,它们具有相同的new_state(3)..然后应该显示id 5,因为没有现有的new_state 3 ..

代码段:

IF OBJECT_ID('TempDB..#tablex','U') IS NOT NULL
      DROP TABLE #tablex

CREATE TABLE #tablex
(
id INT identity primary key,
record_id INT,
date_changed DATETIME,
old_state INT,
new_state INT
)
INSERT INTO #tablex(record_id,date_changed,old_state,new_state)
    SELECT 4,'2009-01-01',0,1 UNION ALL --displayed
    SELECT 4,'2009-01-01',1,2 UNION ALL --displayed
    SELECT 4,'2009-01-01',2,3 UNION ALL --not displayed
    SELECT 4,'2009-01-01',3,2 UNION ALL --not displayed
    SELECT 4,'2009-01-01',2,3 UNION ALL --displayed
    SELECT 4,'2009-01-01',3,4 UNION ALL --not displayed
    SELECT 4,'2009-01-01',4,3           --not displayed

我认为构建结果的顺序很重要..

谢谢!

最佳答案

SELECT A.*
/*
A.ID, A.old_state, a.new_state, 
B.ID as [Next], b.old_state, b.new_state,
C.ID as [Prev],  c.old_state, c.new_state
*/
FROM #table A LEFT JOIN 
#table B ON A.ID = (B.ID - 1)
LEFT JOIN #table C ON (A.ID - 1) = C.ID
-- WHERE A.old_State <> B.new_State AND A.new_State <> C.old_State
WHERE A.record_id = 1
AND A.old_State <> COALESCE(B.new_State, -1) 
AND A.new_State <> COALESCE(C.old_State, -1)

编辑:我猜,OP需要的是剩余的记录应该被选中,除了当前记录的旧状态与下一记录的新状态(记录中的撤销操作的种类)不同的那些记录,当前记录的新状态不应该相同作为以前的记录的旧状态.

点赞