name flag class time
--------------------------------------
M1 A 1 2002-08-12
M1 B 2 2002-08-13
N2 A 1 2002-07-14
N2 A 2 2002-07-27
T3 A 4 2002-08-05
T3 B 1 2002-08-09
T3 D 5 2002-08-11
E7 A 1 2002-04-25
按以下要求检索:
对于相同name值,按时间降序排列,逐个判断flag值,如果flag=B且class=1,则符合;
如果flag=A,class=1,且尚未有flag=B的情况出现,则也符合。
也就是说,要找到所有这样的name,在这个name的不同时期,按时间倒推,只对flag值为B或A的第一条记录感兴趣,如果有这样的记录,必须满足class=1,否则日期继续向前追溯,再次遇到flag=A或B,且class=1的记录,一旦满足条件,此name值不再检索。
如上表,检索结果应为:
N2 A 1 2002-07-14
T3 B 1 2002-08-09
E7 A 1 2002-04-25
请众高手不吝赐教!想加分另开贴!
15 个解决方案
#1
select * from t1 a
where (a.flag=B and a.class= 1)
or ( a.flag = A
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = B)
)
order by time
where (a.flag=B and a.class= 1)
or ( a.flag = A
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = B)
)
order by time
#2
下面的这个已经试过了,没有问题。
select * from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
order by time
select * from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
order by time
#3
不对啊,我只要一条记录,按时间降序的第一条记录,这个我试了,不对
#4
同楼上
#5
刚才没有看清楚,你这里的flag值为B或A的第一条记录感兴趣,好象有歧义,
我是这样理解的如果flag = a ,class=1并且 是第一条记录,如果是flag =b 只要class =1 就可,不管有多少条都选出。
我是这么理解的。
select * from t1 c
where exists(
select name, min(time) from t1 a
where (
(a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'
)
)
)
and a.name =c.name
and a.time =c.time
group by name
)
我是这样理解的如果flag = a ,class=1并且 是第一条记录,如果是flag =b 只要class =1 就可,不管有多少条都选出。
我是这么理解的。
select * from t1 c
where exists(
select name, min(time) from t1 a
where (
(a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'
)
)
)
and a.name =c.name
and a.time =c.time
group by name
)
#6
通过rain11er(清风) 的代码,你的问题应该解决了吧
#7
这100分该rain11er(清风) 拿了,:)
#8
不是啊,不管是flag=A还是flag=B,都只要第一条记录就行了.也就是说要找这样的每个name:在满足class=1并且flag=A或B的记录中进行筛选,按时间降序排列,如果找到一条flag=B,就是它了,如果flag=A,还要满足它的前一条记录(时间比这条记录稍大的一条)不管class是否=1,flag都不能=B
大哥再想想办法吧.谢谢!
大哥再想想办法吧.谢谢!
#9
按你的说法, 好像M1 A 1 ...这条记录应该排在最前面也显示出来呀
#10
M1 A 1不显示,因为虽然有class=1 且falg=A的记录,但它的前一条记录flag=B,要找的条件是,要么flag=B,要么flag=A且前一flag<>B
#11
被你说晕了。
给你提个建议:如果你想把这么大的sql防到程序里面,最好不要这样做。程序不是完成任务就可以了,以后要维护的。如果后来的人接你这一块,你让哪个人怎么活
看到一个这么大的语句。上面的语句我昨天晚上写的,今天再看就晕了。
可能我水平很次,不能写出来,不过我认为如果可以写出来的花,这条sql语句肯定不短,不容易理解。
现在不搞pb了,sql水平下降了不少。以前我们一般都是建立几个临时表进行中转,好理解便于维护。你可以采用这个方法。如果你只是想学sql另当别论。
给你提个建议:如果你想把这么大的sql防到程序里面,最好不要这样做。程序不是完成任务就可以了,以后要维护的。如果后来的人接你这一块,你让哪个人怎么活
看到一个这么大的语句。上面的语句我昨天晚上写的,今天再看就晕了。
可能我水平很次,不能写出来,不过我认为如果可以写出来的花,这条sql语句肯定不短,不容易理解。
现在不搞pb了,sql水平下降了不少。以前我们一般都是建立几个临时表进行中转,好理解便于维护。你可以采用这个方法。如果你只是想学sql另当别论。
#12
如果真想写出来的话,你最好整理一下你的思路,把他完整,清楚的表述出来,尽管你清楚,但别人不清楚,重新再开一个帖子把。
#13
再帮大家UP一下,:)
#14
select name,flag,class,min(time) from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
group by name,flag,class
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
group by name,flag,class
#15
有点头晕,写个procedure吧。
#1
select * from t1 a
where (a.flag=B and a.class= 1)
or ( a.flag = A
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = B)
)
order by time
where (a.flag=B and a.class= 1)
or ( a.flag = A
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = B)
)
order by time
#2
下面的这个已经试过了,没有问题。
select * from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
order by time
select * from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
order by time
#3
不对啊,我只要一条记录,按时间降序的第一条记录,这个我试了,不对
#4
同楼上
#5
刚才没有看清楚,你这里的flag值为B或A的第一条记录感兴趣,好象有歧义,
我是这样理解的如果flag = a ,class=1并且 是第一条记录,如果是flag =b 只要class =1 就可,不管有多少条都选出。
我是这么理解的。
select * from t1 c
where exists(
select name, min(time) from t1 a
where (
(a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'
)
)
)
and a.name =c.name
and a.time =c.time
group by name
)
我是这样理解的如果flag = a ,class=1并且 是第一条记录,如果是flag =b 只要class =1 就可,不管有多少条都选出。
我是这么理解的。
select * from t1 c
where exists(
select name, min(time) from t1 a
where (
(a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'
)
)
)
and a.name =c.name
and a.time =c.time
group by name
)
#6
通过rain11er(清风) 的代码,你的问题应该解决了吧
#7
这100分该rain11er(清风) 拿了,:)
#8
不是啊,不管是flag=A还是flag=B,都只要第一条记录就行了.也就是说要找这样的每个name:在满足class=1并且flag=A或B的记录中进行筛选,按时间降序排列,如果找到一条flag=B,就是它了,如果flag=A,还要满足它的前一条记录(时间比这条记录稍大的一条)不管class是否=1,flag都不能=B
大哥再想想办法吧.谢谢!
大哥再想想办法吧.谢谢!
#9
按你的说法, 好像M1 A 1 ...这条记录应该排在最前面也显示出来呀
#10
M1 A 1不显示,因为虽然有class=1 且falg=A的记录,但它的前一条记录flag=B,要找的条件是,要么flag=B,要么flag=A且前一flag<>B
#11
被你说晕了。
给你提个建议:如果你想把这么大的sql防到程序里面,最好不要这样做。程序不是完成任务就可以了,以后要维护的。如果后来的人接你这一块,你让哪个人怎么活
看到一个这么大的语句。上面的语句我昨天晚上写的,今天再看就晕了。
可能我水平很次,不能写出来,不过我认为如果可以写出来的花,这条sql语句肯定不短,不容易理解。
现在不搞pb了,sql水平下降了不少。以前我们一般都是建立几个临时表进行中转,好理解便于维护。你可以采用这个方法。如果你只是想学sql另当别论。
给你提个建议:如果你想把这么大的sql防到程序里面,最好不要这样做。程序不是完成任务就可以了,以后要维护的。如果后来的人接你这一块,你让哪个人怎么活
看到一个这么大的语句。上面的语句我昨天晚上写的,今天再看就晕了。
可能我水平很次,不能写出来,不过我认为如果可以写出来的花,这条sql语句肯定不短,不容易理解。
现在不搞pb了,sql水平下降了不少。以前我们一般都是建立几个临时表进行中转,好理解便于维护。你可以采用这个方法。如果你只是想学sql另当别论。
#12
如果真想写出来的话,你最好整理一下你的思路,把他完整,清楚的表述出来,尽管你清楚,但别人不清楚,重新再开一个帖子把。
#13
再帮大家UP一下,:)
#14
select name,flag,class,min(time) from t1 a
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
group by name,flag,class
where (a.flag='B' and a.class= 1)
or (a.flag = 'A'
and a.class = 1
and not exists(select * from t1 b
where a.name = b.name
and b.flag = 'B'))
group by name,flag,class
#15
有点头晕,写个procedure吧。