有啥办法可以实现这个功能

[复制链接]
查看11 | 回复8 | 2010-10-8 09:32:25 | 显示全部楼层 |阅读模式
例如我有一个表,里面有两个字段,一个是编码,一个表示件数
编码,件数
A ,3
B ,2
C ,5
我用干什么样子的SQL语句,可以快速的把这个数据展开,变成下面的结果
编码,件数
A,1
A,1
A,1
B,1
B,1
C,1
C,1
C,1
C,1
C,1
有点像聚合的逆操作。

回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
网上看到一个方案,拿来修改后居然可以了,但是不明白prior rn = rn and prior dbms_random.value is not null 是什么意思,有人帮忙解释一下吗?谢谢
with t as (
select 'A' id,3 cnt from dual
union all
select 'B' id,2 cnt from dual
union all
select 'C' id,5 cnt from dual
)
select id , 1(select id,cnt,rownum rn from t) connect by level <= cnt and prior rn = rn and prior dbms_random.value is not null
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
rownum是多余的
with t as (
select 'A' id,3 cnt from dual
union all
select 'B' id,2 cnt from dual
union all
select 'C' id,5 cnt from dual
)
select id, 1
from t
connect by level <= cnt
and prior cnt = cnt
and prior dbms_random.value is not null;
这么写也对。
按照人的思维,
connect by level <= cnt
and prior cnt = cnt
这两个就对了,但是会报错。oracle有一套自己的判断loop的方法。
"if the CONNECT BY condition results in a loop in the hierarchy,then Oracle returns an error.A loop occurs if one row is both the parent(or grandparent or direct ancestor)
and a child(or a grandchild or a direct descendent) of anothor row"
and prior dbms_random.value is not null;可以混淆这个判断。具体原理我也没找到准确的解释。
另外在有些版本里必须用with才能避免loop,有些则可以写下边,甚至直接查表。
select id, 1
from (select 'A' id, 3 cnt

from dual
union all
select 'B' id, 2 cnt

from dual
union all
select 'C' id, 5 cnt from dual)
connect by level <= cnt
and prior cnt = cnt
and prior dbms_random.value is not null;
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi报错
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi, Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production可以
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
nayi224 发表于 2018-4-28 11:33
rownum是多余的
with t as (
select 'A' id,3 cnt from dual

cnt = prior cnt是错的。前后两层应该用主键连接,即 id = prior id
如果没有主键用 rowid 或者先用 rownum 构造出一个唯一的列也可以。
参见以前的讨论:
http://www.itpub.net/thread-1399606-1-1.html
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
直接构造序列法简单,不容易错
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
newkid 发表于 2018-4-28 11:53
cnt = prior cnt是错的。前后两层应该用主键连接,即 id = prior id
如果没有主键用 rowid 或者先用 row ...

谢谢谢谢
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
newkid 发表于 2018-4-28 11:53
cnt = prior cnt是错的。前后两层应该用主键连接,即 id = prior id
如果没有主键用 rowid 或者先用 row ...

那么connect By的用法其实就是一个递归查询,就是用上一层的结果集和当前层进行连接得到新的结果集,然后在和下一层连接,如此循环下去。
但是我还是不太明白为什么加了一个 prior dbms_random.value is not null就不会报错了。
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
lypch 发表于 2018-5-10 18:51
那么connect By的用法其实就是一个递归查询,就是用上一层的结果集和当前层进行连接得到新的结果集,然后 ...

我发的链接里面讨论了这一现象,特别是40楼之后的内容。
回复

使用道具 举报

千问 | 2010-10-8 09:32:25 | 显示全部楼层
学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行