SQL Server如何在同一张表里进行行对比,输出某列值改变的行

mofei0503 2016-11-23 11:31:17
#SQL Server如何在同一张表里进行行对比,输出某列值改变的行,最终还要显示在SSRS报表中作为一个dataset#

原始表见表一,记录的时候每个人每天的排班情况,有的人又是会改变班次,又shift 变为non-shift或者由non-shift变为shift。现在需要找出在当月排班改变的人的记录,输出另一张表。
比如这两个人,ID是786636和786656分别在8/10和7/27排班改变了,然后输出表二。
原始表数据较多,大概4万条,而且是动态的 每个月都会有更新。
原始表:
输出表:
...全文
842 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
shoppo0505 2016-11-25
  • 打赏
  • 举报
回复
引用 12 楼 S_SUNY_1234 的回复:
[quote=引用 8 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 98663, 'Shift', '2016.07.25' union all select 98663, 'Shift', '2016.07.26' union all select 98663, 'Shift', '2016.07.21' union all select 9866, 'Shift', '2016.07.22' union all select 9866, 'Non-Shift', '2016.07.23' union all select 9866, 'Non-Shift', '2016.07.24' union all select 9866, 'Shift', '2016.07.25' union all select 9866, 'Shift', '2016.07.26' union all select 9866, 'Shift', '2016.07.21' union all select 986, 'Shift', '2016.07.22' union all select 986, 'Non-Shift', '2016.07.23' union all select 986, 'Non-Shift', '2016.07.24' union all select 986, 'Shift', '2016.07.25' union all select 986, 'Shift', '2016.07.26' union all select 986, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over(partition by _ID order by _date ) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index, a._ID --a._ID, a._shift, a._date from data a left outer join data b on a._index = b._index + 1 and a._shift <> b._shift and a._ID = b._ID where b._index is not null ) --select distinct * from indexdata select distinct _ID, _shift, _date from data where data._index in (select a_index from indexdata where _ID = data._id) or data._index in (select b_index from indexdata where _ID = data._id) order by _ID, _date
您好,这张表只是一部分,并不是全部,大概有3万多条,with 里的select 语句应该怎么写呢,直接写成[/quote] 看来你一点基础都没有啊。 with中的第一部分省略就行了, 使用的列名你自己再根据你的情况再修改一下。 with data as( select _index = ROW_NUMBER()over(partition by _ID order by _date ) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index, a._ID --a._ID, a._shift, a._date from data a left outer join data b on a._index = b._index + 1 and a._shift <> b._shift and a._ID = b._ID where b._index is not null ) --select distinct * from indexdata select distinct _ID, _shift, _date from data where data._index in (select a_index from indexdata where _ID = data._id) or data._index in (select b_index from indexdata where _ID = data._id) order by _ID, _date
mofei0503 2016-11-23
  • 打赏
  • 举报
回复
引用 1 楼 shoppo0505 的回复:
with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
谢谢您的回复,原始表中有很多这种数据,那两个人只是一个例子,如果要找到所有排班改变的人,是不是可以写成 select ID,shift,date
  • 打赏
  • 举报
回复
引用 1 楼 shoppo0505 的回复:
with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?
shoppo0505 2016-11-23
  • 打赏
  • 举报
回复
with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
mofei0503 2016-11-23
  • 打赏
  • 举报
回复
引用 8 楼 shoppo0505 的回复:
with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 98663, 'Shift', '2016.07.25' union all select 98663, 'Shift', '2016.07.26' union all select 98663, 'Shift', '2016.07.21' union all select 9866, 'Shift', '2016.07.22' union all select 9866, 'Non-Shift', '2016.07.23' union all select 9866, 'Non-Shift', '2016.07.24' union all select 9866, 'Shift', '2016.07.25' union all select 9866, 'Shift', '2016.07.26' union all select 9866, 'Shift', '2016.07.21' union all select 986, 'Shift', '2016.07.22' union all select 986, 'Non-Shift', '2016.07.23' union all select 986, 'Non-Shift', '2016.07.24' union all select 986, 'Shift', '2016.07.25' union all select 986, 'Shift', '2016.07.26' union all select 986, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over(partition by _ID order by _date ) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index, a._ID --a._ID, a._shift, a._date from data a left outer join data b on a._index = b._index + 1 and a._shift <> b._shift and a._ID = b._ID where b._index is not null ) --select distinct * from indexdata select distinct _ID, _shift, _date from data where data._index in (select a_index from indexdata where _ID = data._id) or data._index in (select b_index from indexdata where _ID = data._id) order by _ID, _date
您好,这张表只是一部分,并不是全部,大概有3万多条,with 里的select 语句应该怎么写呢,直接写成
gw6328 2016-11-23
  • 打赏
  • 举报
回复

with tb(_ID, _shift, _date) as
(
select 986636, 'Shift', '2016.07.21' union all
select 986636, 'Shift', '2016.07.22' union all
select 986636, 'Non-Shift', '2016.07.23' union all
select 986636, 'Non-Shift', '2016.07.24' union ALL
select 986636, 'Non-Shift', '2016.07.25' union all
select 986636, 'Shift', '2016.07.26' union all
select 986636, 'Shift', '2016.07.27' union all
select 986636, 'Shift', '2016.07.28'
),
cte AS (
	SELECT rn=ROW_NUMBER() OVER(ORDER BY _date),* FROM tb
)
SELECT * FROM cte a  JOIN cte b ON ABS(a.rn-b.rn)=1 WHERE a.[_shift]<>b.[_shift]
Ginnnnnnnn 2016-11-23
  • 打赏
  • 举报
回复
with tb(_ID, _shift, _date) as
(
select 986636, 'Shift', '2016.07.21' union all
select 986636, 'Shift', '2016.07.22' union all
select 986636, 'Non-Shift', '2016.07.23' union all
select 986636, 'Non-Shift', '2016.07.24' union ALL
select 986636, 'Non-Shift', '2016.07.25' union all
select 986636, 'Shift', '2016.07.26' union all
select 986636, 'Shift', '2016.07.27' union all
select 986636, 'Shift', '2016.07.28'
)
,CTE AS(
	SELECT *,
			ROW_NUMBER() OVER (PARTITION BY tb._ID ORDER BY tb._date) AS RNr		
		FROM tb
)
SELECT * FROM CTE b WHERE EXISTS(
SELECT *
	FROM CTE a
	WHERE EXISTS(SELECT * FROM CTE WHERE a._ID = CTE._ID AND RNr = a.RNr + 1 AND a._shift <> CTE._shift) 
	  AND b.RNr IN (a.RNr,a.RNr+1))
	
道素 2016-11-23
  • 打赏
  • 举报
回复
不考虑性能因素,你看看下面的,思路是取得当前记录的上一版和下一班 和相邻不同的就输出

with tb(ID, shift, d) as
(
select 986636, 'Shift', '2016.07.21' union all
select 986636, 'Shift', '2016.07.22' union all
select 986636, 'Non-Shift', '2016.07.23' union all
select 986636, 'Non-Shift', '2016.07.24' union all
select 986636, 'Shift', '2016.07.25' union all
select 986636, 'Shift', '2016.07.26' union all
select 986636, 'Shift', '2016.07.27'
)
SELECT t.*,t1.shift,t2.shift 
FROM tb AS t
OUTER APPLY (SELECT TOP 1 pt.shift FROM tb AS pt WHERE pt.id=t.id AND pt.d<t.d ORDER BY pt.d DESC ) t1
OUTER APPLY (SELECT TOP 1 lt.shift FROM tb AS lt WHERE lt.id=t.id AND lt.d>t.d ORDER BY lt.d  ) t2
WHERE t.shift!= ISNULL(t1.shift,t.shift) OR t.shift!=ISNULL(t2.shift,t.shift)
/*
ID          shift     d
----------- --------- ----------
986636      Shift     2016.07.22
986636      Non-Shift 2016.07.23
986636      Non-Shift 2016.07.24
986636      Shift     2016.07.25
*/
shoppo0505 2016-11-23
  • 打赏
  • 举报
回复
with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 98663, 'Shift', '2016.07.25' union all select 98663, 'Shift', '2016.07.26' union all select 98663, 'Shift', '2016.07.21' union all select 9866, 'Shift', '2016.07.22' union all select 9866, 'Non-Shift', '2016.07.23' union all select 9866, 'Non-Shift', '2016.07.24' union all select 9866, 'Shift', '2016.07.25' union all select 9866, 'Shift', '2016.07.26' union all select 9866, 'Shift', '2016.07.21' union all select 986, 'Shift', '2016.07.22' union all select 986, 'Non-Shift', '2016.07.23' union all select 986, 'Non-Shift', '2016.07.24' union all select 986, 'Shift', '2016.07.25' union all select 986, 'Shift', '2016.07.26' union all select 986, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over(partition by _ID order by _date ) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index, a._ID --a._ID, a._shift, a._date from data a left outer join data b on a._index = b._index + 1 and a._shift <> b._shift and a._ID = b._ID where b._index is not null ) --select distinct * from indexdata select distinct _ID, _shift, _date from data where data._index in (select a_index from indexdata where _ID = data._id) or data._index in (select b_index from indexdata where _ID = data._id) order by _ID, _date
mofei0503 2016-11-23
  • 打赏
  • 举报
回复
引用 5 楼 baidu_36457652 的回复:
[quote=引用 4 楼 shoppo0505 的回复:] [quote=引用 2 楼 baidu_36457652 的回复:] [quote=引用 1 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?[/quote] 如果有不同的ID,那就需要添加partition by id[/quote] 他上面的表中 又不同的id[/quote]
引用 6 楼 shoppo0505 的回复:
[quote=引用 5 楼 baidu_36457652 的回复:] [quote=引用 4 楼 shoppo0505 的回复:] [quote=引用 2 楼 baidu_36457652 的回复:] [quote=引用 1 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?[/quote] 如果有不同的ID,那就需要添加partition by id[/quote] 他上面的表中 又不同的id[/quote] 还真是,我以为是一个呢。 ID 这一列有很多个id,大概3000多,要怎么样才能得到Shift变化的人的记录,我试着写存储过程,里面的逻辑越写越乱,返回来的表也是空的,您能不能帮忙写下,将Shift 改变的人都集中到一张表。谢谢
shoppo0505 2016-11-23
  • 打赏
  • 举报
回复
引用 5 楼 baidu_36457652 的回复:
[quote=引用 4 楼 shoppo0505 的回复:] [quote=引用 2 楼 baidu_36457652 的回复:] [quote=引用 1 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?[/quote] 如果有不同的ID,那就需要添加partition by id[/quote] 他上面的表中 又不同的id[/quote] 还真是,我以为是一个呢。
  • 打赏
  • 举报
回复
引用 4 楼 shoppo0505 的回复:
[quote=引用 2 楼 baidu_36457652 的回复:] [quote=引用 1 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?[/quote] 如果有不同的ID,那就需要添加partition by id[/quote] 他上面的表中 又不同的id
shoppo0505 2016-11-23
  • 打赏
  • 举报
回复
引用 2 楼 baidu_36457652 的回复:
[quote=引用 1 楼 shoppo0505 的回复:] with tb(_ID, _shift, _date) as ( select 986636, 'Shift', '2016.07.21' union all select 986636, 'Shift', '2016.07.22' union all select 986636, 'Non-Shift', '2016.07.23' union all select 986636, 'Non-Shift', '2016.07.24' union all select 986636, 'Shift', '2016.07.25' union all select 986636, 'Shift', '2016.07.26' union all select 986636, 'Shift', '2016.07.27' ) , data as( select _index = ROW_NUMBER()over( order by _date) , * from tb ) , indexdata as ( select a._index as a_index, b._index as b_index from data a left outer join data b on a._index = b._index + 1 where a._shift <> b._shift ) select _ID, _shift, _date from data where data._index in (select a_index from indexdata) or data._index in (select b_index from indexdata)
大哥 这个_index = ROW_NUMBER()over( order by _date) 是否应该 加个 partition by id?[/quote] 如果有不同的ID,那就需要添加partition by id

590

社区成员

发帖
与我相关
我的任务
社区描述
提出问题
其他 技术论坛(原bbs)
社区管理员
  • community_281
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧