关于表数据处理的SQL

Yanhuogege 2019-08-12 11:41:11
版主,各位大神好,请教问题,表数据按“FacilityID","BeginDate”字段排序后,数量(WorkerNumber)一样且不中断的分成一组并取最小日期数据。如下图所示,依次分成4组。
这种数据提取该如何做呢? 目前我只想到用游标或while循环数据去提取的方法 (也就是下一笔比较上一笔)。感觉这种是最笨的方法,
想问:有没有其他用sql语句(嵌套)能解决的方法?
...全文
189 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 1 楼 Hello World,的回复:
lag和lead函数正适合你
好的,这两个函数没用过,研究研究
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 2 楼 woobol的回复:
要达到什么效果?
就是如图所示,分成四组,每组里取最大或最小日期一笔数据。
woobol 2019-08-12
  • 打赏
  • 举报
回复
要达到什么效果?
Hello World, 2019-08-12
  • 打赏
  • 举报
回复
lag和lead函数正适合你
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 9 楼 RINK_1 的回复:

IF OBJECT_ID(N'TEMPDB.DBO.#T') IS NOT NULL
DROP TABLE #T
GO

CREATE TABLE #T(FACILITYID INT,BEGINDATE DATE,WORKERNUMBER INT)
INSERT INTO #T
SELECT 1,'2019-07-01',25 UNION ALL
SELECT 1,'2019-07-02',24 UNION ALL
SELECT 1,'2019-07-05',24 UNION ALL
SELECT 1,'2019-07-06',24 UNION ALL
SELECT 1,'2019-07-12',24 UNION ALL
SELECT 1,'2019-07-15',24 UNION ALL
SELECT 1,'2019-07-16',24 UNION ALL
SELECT 1,'2019-07-20',23 UNION ALL
SELECT 1,'2019-07-22',23 UNION ALL
SELECT 1,'2019-07-25',23 UNION ALL
SELECT 1,'2019-08-02',24 UNION ALL
SELECT 1,'2019-07-18',23
GO

WITH CTE
AS
(SELECT *,ROW_NUMBER() OVER (ORDER BY FACILITYID,BEGINDATE) AS SEQ FROM #T)

SELECT * FROM CTE A
WHERE SEQ=1 OR (EXISTS (SELECT 1 FROM CTE WHERE SEQ=A.SEQ-1 AND A.WORKERNUMBER<>WORKERNUMBER))


9楼朋友,抱歉,没留意到你也给予帮助回复了本帖 没给到分。
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 11 楼 二月十六 的回复:
理解的确实有点问题,重写了一下


非常感谢版主的热情帮助!
最后的就正确了,咋一看这种关联方式有点不太好理解,还好 这种写法还经常用看懂了。

另外感谢1楼的兄弟 ,告知lead,LAG函数,这种我做出来了,跟版主的结果一致,这俩函数确实没用过,学到了,感谢!

结贴,给分!
二月十六 2019-08-12
  • 打赏
  • 举报
回复
理解的确实有点问题,重写了一下
二月十六 2019-08-12
  • 打赏
  • 举报
回复
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-03',25 union all
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-07',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-12',23 union all
select 1,'2019-07-13',23 union all
select 1,'2019-07-15',23 union all
select 1,'2019-07-16',24 union all
select 1,'2019-07-17',24 union all
select 1,'2019-07-18',24
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT *,ROW_NUMBER()OVER(PARTITION BY t.WorkerNumber,rn ORDER BY t.BeginDate) rn1 FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY WorkerNumber ORDER BY FacilityID, BeginDate)
- ROW_NUMBER() OVER (ORDER BY FacilityID, BeginDate) rn
FROM #T)t)t1 WHERE t1.rn1=1 ORDER BY t1.BeginDate


RINK_1 2019-08-12
  • 打赏
  • 举报
回复

IF OBJECT_ID(N'TEMPDB.DBO.#T') IS NOT  NULL
DROP TABLE #T
GO

CREATE TABLE #T(FACILITYID INT,BEGINDATE DATE,WORKERNUMBER INT)
INSERT INTO #T
SELECT 1,'2019-07-01',25 UNION ALL
SELECT 1,'2019-07-02',24 UNION ALL
SELECT 1,'2019-07-05',24 UNION ALL
SELECT 1,'2019-07-06',24 UNION ALL
SELECT 1,'2019-07-12',24 UNION ALL
SELECT 1,'2019-07-15',24 UNION ALL
SELECT 1,'2019-07-16',24 UNION ALL
SELECT 1,'2019-07-20',23 UNION ALL
SELECT 1,'2019-07-22',23 UNION ALL
SELECT 1,'2019-07-25',23 UNION ALL
SELECT 1,'2019-08-02',24 UNION ALL
SELECT 1,'2019-07-18',23
GO

WITH CTE
AS
(SELECT *,ROW_NUMBER() OVER (ORDER BY FACILITYID,BEGINDATE) AS SEQ FROM #T)

SELECT * FROM CTE A
WHERE SEQ=1 OR (EXISTS (SELECT 1 FROM CTE WHERE SEQ=A.SEQ-1 AND A.WORKERNUMBER<>WORKERNUMBER))
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 7 楼 二月十六 的回复:
[quote=引用 6 楼 zkingedit 的回复:][quote=引用 5 楼 二月十六 的回复:]
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-08',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-22',23 union all
select 1,'2019-07-23',23 union all
select 1,'2019-07-24',23
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT * ,ROW_NUMBER()OVER(PARTITION BY t.mindate ORDER BY t.BeginDate) rn FROM (
Select *,DATEADD(DAY,-ROW_NUMBER()OVER(ORDER BY FacilityID)+1,BeginDate) AS mindate from #T
)t)t1 WHERE rn=1




感谢版主回复,看到这个需求时,我首先想到的也是partition by,但没想一个先产生mindate的方法,但版主这个还有一个bug,当日期不延续时mindate 就不对了。
[/quote]日期不连续就不算一个组了,不是这样理解吗?如果理解的不对,建议楼主按照我写的测试数据给出正确的结果,或者我的测试数据不具有代表性,楼主自己写测试数据和对应想要的结果。[/quote]

感谢版主热情解答!
需求就是:按产线ID,日期排序后,数量连续不变的则分为一组并取组内日期最小那条记录。 如图中:数量=24的算两组,因为中间被23隔断。

--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-03',25 union all
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-07',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-12',23 union all
select 1,'2019-07-13',23 union all
select 1,'2019-07-15',23 union all
select 1,'2019-07-16',24 union all
select 1,'2019-07-17',24 union all
select 1,'2019-07-18',24
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT * ,ROW_NUMBER()OVER(PARTITION BY t.mindate ORDER BY t.BeginDate) rn FROM (
Select *,DATEADD(DAY,-ROW_NUMBER()OVER(ORDER BY FacilityID)+1,BeginDate) AS mindate from #T
)t)t1 WHERE rn=1

二月十六 2019-08-12
  • 打赏
  • 举报
回复
引用 6 楼 zkingedit 的回复:
[quote=引用 5 楼 二月十六 的回复:]
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-08',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-22',23 union all
select 1,'2019-07-23',23 union all
select 1,'2019-07-24',23
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT * ,ROW_NUMBER()OVER(PARTITION BY t.mindate ORDER BY t.BeginDate) rn FROM (
Select *,DATEADD(DAY,-ROW_NUMBER()OVER(ORDER BY FacilityID)+1,BeginDate) AS mindate from #T
)t)t1 WHERE rn=1




感谢版主回复,看到这个需求时,我首先想到的也是partition by,但没想一个先产生mindate的方法,但版主这个还有一个bug,当日期不延续时mindate 就不对了。
[/quote]日期不连续就不算一个组了,不是这样理解吗?如果理解的不对,建议楼主按照我写的测试数据给出正确的结果,或者我的测试数据不具有代表性,楼主自己写测试数据和对应想要的结果。
Yanhuogege 2019-08-12
  • 打赏
  • 举报
回复
引用 5 楼 二月十六 的回复:
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-08',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-22',23 union all
select 1,'2019-07-23',23 union all
select 1,'2019-07-24',23
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT * ,ROW_NUMBER()OVER(PARTITION BY t.mindate ORDER BY t.BeginDate) rn FROM (
Select *,DATEADD(DAY,-ROW_NUMBER()OVER(ORDER BY FacilityID)+1,BeginDate) AS mindate from #T
)t)t1 WHERE rn=1




感谢版主回复,看到这个需求时,我首先想到的也是partition by,但没想一个先产生mindate的方法,但版主这个还有一个bug,当日期不延续时mindate 就不对了。
二月十六 2019-08-12
  • 打赏
  • 举报
回复
--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([FacilityID] int,[BeginDate] Date,[WorkerNumber] int)
Insert #T
select 1,'2019-07-05',25 union all
select 1,'2019-07-06',25 union all
select 1,'2019-07-08',24 union all
select 1,'2019-07-09',24 union all
select 1,'2019-07-10',24 union all
select 1,'2019-07-22',23 union all
select 1,'2019-07-23',23 union all
select 1,'2019-07-24',23
Go
--测试数据结束
SELECT t1.FacilityID,t1.BeginDate,t1.WorkerNumber FROM (
SELECT * ,ROW_NUMBER()OVER(PARTITION BY t.mindate ORDER BY t.BeginDate) rn FROM (
Select *,DATEADD(DAY,-ROW_NUMBER()OVER(ORDER BY FacilityID)+1,BeginDate) AS mindate from #T
)t)t1 WHERE rn=1


22,296

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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