提问人:emare 提问时间:10/20/2023 最后编辑:emare 更新时间:10/21/2023 访问量:61
透视未知字段值 [重复]
Pivot an unknown field value [duplicate]
问:
我正在运行 Oracle 11。
我有一个客户参考资料表,上面有要打印的文件。有很多类型的文件,我事先并不了解它们。shorto04
下面是一个数据示例:
短O04 | wdocname |
---|---|
7739096 | SL00A系列 |
7739096 | TR00A系列 |
7740767 | AV00BITA |
7768159 | SL00AFRA |
7768159 | TR00AFRA |
7768159 | AD00AFRA |
7768159 | PL00AFRA |
7771629 | SL00A系列 |
7780966 | TR00A系列 |
7780966 | AD00A型 |
7812187 | SL00A系列 |
7812187 | TR00A系列 |
7812187 | AD00A型 |
7817697 | SL00AGBR |
7817697 | TR00AGBR |
7817697 | AV00BGBR |
7818401 | SL00AGBR |
7818401 | TR00AGBR |
7818412 | SL00AGBR |
7818412 | TR00AGBR |
7829375 | SL00AGBR |
7829375 | TR00AGBR |
7829375 | PL00AGBR |
7832296 | SL00A系列 |
7832296 | TR00A系列 |
7832296 | AD00A型 |
7832297 | SL00A系列 |
7832297 | TR00A系列 |
7832297 | AD00A型 |
7840205 | OD00IGBR |
7840205 | SL00DGBR |
7840205 | AV00DGBR |
老板要求计算所有不同的类型以及我们有多少。 所以我从一个像belolw这样的查询开始:
Select *
from
(
select shorto04, SUBSTR(wdocname, 1,5) as docs
from O04T91
)
pivot
(
count(docs)
for docs in ( 'TR00A' , 'OD00A')
)
当然,我的sql结果与我需要的相去甚远:
短O04 | tr00a_ | od00a_ |
---|---|---|
7709902 | 1,000000 | 0,000000 |
7725337 | 1,000000 | 0,000000 |
7729012 | 1,000000 | 0,000000 |
7729062 | 1,000000 | 0,000000 |
7739096 | 1,000000 | 0,000000 |
7740767 | 1,000000 | 1,000000 |
7768159 | 1,000000 | 0,000000 |
7771629 | 1,000000 | 0,000000 |
使用我的方法,我需要在查询中对所有可能的文档类型进行硬编码,如果有任何新的文档类型,它们将不会被计算在内。
下面是部分预期结果的示例:
短O04 | TR00A系列 | OD00A型 | AD00A系列 | AV00B系列 | SL00A系列 | OD00i型 | AV00D系列 | 等 | 等 | 等 | 等 |
---|---|---|---|---|---|---|---|---|---|---|---|
7709902 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7725337 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7729012 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | ||||
7729062 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | ||||
7739096 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7740767 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | ||||
7768159 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7771629 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7780966 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7812187 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7817697 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | ||||
7818401 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | ||||
7818412 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | ||||
7829375 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | ||||
7832296 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7832297 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ||||
7840205 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | ||||
7840228 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
任何帮助将不胜感激。 谢谢
答:
1赞
Lajos Arpad
10/20/2023
#1
您可以通过以下方式选择不同的值
select distinct wdocname
from shorto04;
并生成如下所示的查询:
SELECT
'SELECT Shorto04, ' ||
LISTAGG(
'(SELECT COUNT(*) FROM ORDREF tmp WHERE tmp.shorto04 = ORDREF.shorto04 and wdocname = ''' ||
wdocname ||
''') AS ' ||
wdocname ||
' FROM ORDREF GROUP BY Shorto04;'
, ',') WITHIN GROUP(ORDER BY wdocname) AS query
FROM (
SELECT DISTINCT wdocname
FROM ORDREF
) t;
SELECT Shorto04,
(SELECT COUNT(*) FROM ORDREF tmp WHERE tmp.shorto04 = ORDREF.shorto04 and wdocname = 'OD00A') AS OD00A,
(SELECT COUNT(*) FROM ORDREF tmp WHERE tmp.shorto04 = ORDREF.shorto04 and wdocname = 'TR00A') AS TR00A
FROM ORDREF
GROUP BY Shorto04;
基本上,您添加主列,然后以逗号分隔的方式选择子列,将 distinct 作为输入。查询未经测试。如果您使用示例数据创建 SQL Fiddle,我很乐意对其进行更实际的测试。wdocname
编辑
由于提供了 SQL Fiddle,我能够在实践中测试查询,并且我已经调整了查询以在实践中工作。已经在上面更新了。
小提琴链接: http://www.sqlfiddle.com/#!4/cd7e3/1
第一个查询,即此答案中共享的查询,生成要作为文本实际执行的查询。Oracle 能够将文本作为查询执行,请参阅:Oracle SQL 查询能否执行从表中选择的字符串查询?
评论
0赞
emare
10/20/2023
这是我第一次尝试 SQL Fiddle sqlfiddle.com/#!9/72d450/1
0赞
MT0
10/20/2023
这看起来像未经测试的代码。如果你测试过它,你会发现缺少逗号,其他地方有太多的逗号,然后当你修复这些错误时,你会发现它只需要 2 个参数。CONCAT
0赞
Lajos Arpad
10/21/2023
@MT0它确实是未经测试的代码,正如我在答案中澄清的那样,因为没有输入可以处理。由于 Emare 已经发送了一把小提琴,我打算研究它并调整代码。
0赞
Lajos Arpad
10/21/2023
@emare谢谢你的小提琴。相应地修复了代码,请在答案和我给出的链接中查看。
0赞
Lajos Arpad
10/21/2023
@MT0编辑了我的答案,所以现在代码是正确的,因为我们现在有一个正确的输入。
评论