select
id
,k||
'*'
||
sum
(decode(k,
'0'
,
0
,
1
)) x
from
(
select
id
,num,rn,
(
case
when
rn
like
'%1111111%'
then
'
特等奖
'
when
rn
like
'%111111%'
then
'
一等奖
'
when
rn
like
'%11111%'
then
'
二等奖
'
when
rn
like
'%1111%'
then
'
三等奖
'
when
rn
like
'%111%'
then
'
四等奖
'
when
rn
like
'%11%'
then
'
五等奖
'
else
'0'
end
) k
from
(
select
id
,num,a||b||c||d||e||f||g rn
from
(
select
id
,num,
decode(a.a,w.a,
1
,
0
) a,
decode(a.b,w.b,
1
,
0
) b,
decode(a.c,w.c,
1
,
0
) c,
decode(a.d,w.d,
1
,
0
) d,
decode(a.e,w.e,
1
,
0
) e,
decode(a.f,w.f,
1
,
0
) f,
decode(a.g,w.g,
1
,
0
) g
from
(
select
id
,num,substr(num,
1
,
1
) a,substr(num,
2
,
1
) b,substr(num,
3
,
1
) c,
substr(num,
4
,
1
) d,substr(num,
5
,
1
) e,substr(num,
6
,
1
) f,substr(num,
7
,
1
) g
from
t9) a,
(
select
&
1
a,&
2
b,&
3
c,&
4
d,&
5
e,&
6
f,&
7
g
from
dual) w
--输入
每期中将号码
)
)
)
group
by
id
,k
having
sum
(decode(k,
'0'
,
0
,
1
))<>
0--不显示未中奖者名单
;
另外涉及到这个题目的一些衍生问题,如
每个ID只生成一条记录,所有号用“,”分开,如何转换为T9中的格式:
由于每一组号码的长度是固定的(7位),所以可以根据字段长度来半段出某个ID购买了几注——(length(num)+1)/8
这样可以使用一下代码将每一注号码区分出来:
create
table
t8 (
id
varchar2
(
6
),num
varchar2
(
999
));
insert
into
t8
values
(
'10001'
,
'7483627,5693268,1259026,0326597,1265975,1236498,0031699,1258962,1359871,1326987'
);
insert
into
t8
values
(
'10002'
,
'9623584,1236895,2156298,2356897,2369654,1259864,2145236'
);
insert
into
t8
values
(
'10003'
,
'1234569,1236598,1254785,1254696,1268954'
);
insert
into
t8
values
(
'10004'
,
'3298648'
);
commit
;
select
distinct
a.id,substr(a.num,instr(a.num,
','
,
1
,b.rn)+
1
,
7
) num
from
(
select
id
,num
from
t8) a,
(
select
rownum
rn
from
dual
connect
by
rownum
<=
100
) b
order
by
1
,
2
通过instr函数找到“,”的位置,然后通过substr找到号码。如果号码的位数不确定,也可以通过
instr(num,',',1,rn+1)-instr(num,',',1,rn)
来计算位数,从而得到结果。
这里直接使用rownum<=100,限制了每个ID的数量,而且直接使用了hash join,会造成系统效率比较低,暂时没有考虑优化的问题。
关于一般的彩票中存在的数字不重复,且无需按位数排列,或者数字可选两位数等等,写PLSQL要比直接写SQL代码简单得多,以后有空再整理一下。