sql查询语句写法求助

假设有一张表如下,这张表已经按姓名和时间排序,我要求每个人最近的一个分类最早的时间,但是这个分类不可以在时间上进行变化,比如现在是2024年,张三的时间离现在最近的分类是A,而在时间离现在最近且分类为A,同时分类不变化的数据即前3条,最后一条时间为2018的张三的数据,虽然分类也为A,但是从这条数据到上条分类为A的数据之间有其他分类,所以这条数据不算在内,最后从得到的前三条数据中求得最早时间2022,这个时间就是张三对应的时间,也就是我想要的数据,这种sql语句怎么写呢?

sql:sqlserver

image.png

对于上图例子我想要的结果:

image.png

SQL 黄色小鸡 发布于 2024-12-18 15:35 (编辑于 2024-12-18 16:10)
1min目标场景问卷 立即参与
回答问题
悬赏:3 F币 + 添加悬赏
提示:增加悬赏、完善问题、追问等操作,可使您的问题被置顶,并向所有关注者发送通知
共6回答
最佳回答
0
snrtuemcLv8专家互助
发布于2024-12-18 15:39(编辑于 2024-12-18 15:40)

张三A分类最早不是2018吗?

你要连续的最早那个?那李四的规律又如何

  • 黄色小鸡 黄色小鸡(提问者) 分类不可以变化,张三的那个A分类离最新的A分类中间隔着其他分类B、C,李四的规律和张三一样
    2024-12-18 16:13 
最佳回答
0
华莉星宸Lv7资深互助
发布于2024-12-18 15:41

你把你想要的结果,在贴个图出来看看

最佳回答
0
Z4u3z1Lv6专家互助
发布于2024-12-18 15:41

问SQL要备注你是什么数据库:oracle?mysql?SqlServer 等待

最佳回答
0
用户k6280494Lv6资深互助
发布于2024-12-18 15:48

SELECT xm,sj,fl FROM table a WHERE sj=(SELECT min(sj) FROM table b WHERE a.fl=b.fl)

最佳回答
0
0035705Lv5初级互助
发布于2024-12-18 16:19(编辑于 2024-12-19 15:45)

select * from (

select a.*,ROW_NUMBER() OVER (partition by 姓名,cc ORDER BY 时间 desc,cc ASC) paixu  from (

SELECT 

姓名,

分类,

时间

,时间-1 as aa

  ,lead(时间,1,0) over(partition by 姓名,分类 order by 时间 desc) as bb

  ,case when 时间-1 != lead(时间,1,0) over(partition by 姓名,分类 order by 时间 desc) then 1 else null end cc

FROM (select distinct 姓名,分类,时间 from 分类) a

-- order by 姓名,时间 desc

) a

where cc is not null

)a 

where

paixu=1

image.png

image.png

他们的都太复杂  看这个

  • 黄色小鸡 黄色小鸡(提问者) 这里“时间-1”是针对我这个模拟数据的写法,如果我的时间变成具体的年月日,并且不一定是连续的,sql写法怎么修改呢
    2024-12-19 12:14 
  • 0035705 0035705 回复 黄色小鸡(提问者) 你不是要连续的吗,
    2024-12-19 13:36 
  • 0035705 0035705 回复 黄色小鸡(提问者) 把真实数据的结构贴上来
    2024-12-19 13:37 
  • 0035705 0035705 回复 黄色小鸡(提问者) 那就给他改为日期减1天
    2024-12-19 13:43 
  • 黄色小鸡 黄色小鸡(提问者) 回复 0035705 试过但结果不正确
    2024-12-19 15:19 
最佳回答
0
JL98Lv6中级互助
发布于2024-12-18 17:03

image.png

with t1 as (

select  '张三' as name,'A' as Category,2018 as Year

union

select  '张三' as name,'C' as Category,2019 as Year

union

select  '张三' as name,'B' as Category,2020 as Year

union

select  '张三' as name,'C' as Category,2021 as Year

union

select  '张三' as name,'A' as Category,2022 as Year

union

select  '张三' as name,'A' as Category,2023 as Year

union

select  '张三' as name,'A' as Category,2024 as year

union

select  '李四' as name,'C' as Category,2021 as Year

union

select  '李四' as name,'A' as Category,2022 as Year

union

select  '李四' as name,'B' as Category,2023 as Year

union

select  '李四' as name,'B' as Category,2024 as Year

)

,  RankedRecords AS (

SELECT

Name,

Year,

Category,

ROW_NUMBER() OVER (PARTITION BY Name, Category ORDER BY Year) AS RowAsc,

ROW_NUMBER() OVER (PARTITION BY Name, Category ORDER BY Year DESC) AS RowDesc,

COUNT(*) OVER (PARTITION BY Name, Category) AS CountInCategory

FROM

t1

),

Groups AS (

SELECT

Name,

Year,

Category,

Year - ROW_NUMBER() OVER (PARTITION BY Name, Category ORDER BY Year) AS GroupId

FROM

RankedRecords

),

ContinuousYears AS (

SELECT

Name,

MIN(Year) AS StartYear,

MAX(Year) AS EndYear,

Category,

COUNT(*) AS YearsCount

FROM

Groups

GROUP BY

Name,

Category,

GroupId

),

LatestCategory AS (

SELECT

Name,

Category,

MAX(EndYear) AS MaxEndYear

FROM

(

SELECT

Name,

Category,

EndYear,

ROW_NUMBER() OVER (PARTITION BY Name ORDER BY EndYear DESC, Category DESC) AS RowNum

FROM

ContinuousYears

) AS RankedLatest

WHERE

RowNum = 1

GROUP BY

Name,

Category

),

Result AS (

SELECT

c.Name,

c.StartYear AS EarliestContinuousYear,

lc.Category

FROM

ContinuousYears c

JOIN

LatestCategory lc ON c.Name = lc.Name AND c.Category = lc.Category AND c.EndYear = lc.MaxEndYear

)

SELECT

Name,

EarliestContinuousYear,

Category

FROM

Result;

  • 6关注人数
  • 112浏览人数
  • 最后回答于:2024-12-19 15:45
    请选择关闭问题的原因
    确定 取消
    返回顶部