Oracle10G SQL︰ 车削栏目走进行

标签: sql Oracle
发布时间: 2017/4/15 19:05:12
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我需要列变成行并得到其平均。

例如我有此表︰

Name   Math    Science     Computer
----   ----    -------     --------
Ted    90       89          95
Zed    99       98          98
Fed    85       75          90

输出应该是︰

Subject      Average
-------      -------
Math         88
Science      87.33
Computer     94.33

如何能做到?谢谢你的帮助。

解决方法 1:

如果你在 11 G 你可以使用 unpivot :

SELECT subject, AVG(percentage) AS percentage
FROM (
    SELECT * FROM tablea
    UNPIVOT (percentage FOR subject IN (math, science, computer))
)
GROUP BY subject
ORDER BY subject;

SUBJECT  PERCENTAGE
-------- ----------
COMPUTER      94.33
MATH          91.33
SCIENCE       87.33

但因为你不是,你能模仿它。适应从这个网站

SELECT subject, AVG(percentage) AS percentage
FROM (
    SELECT DECODE(unpivot_row, 1, 'Math',
                               2, 'Science',
                               3, 'Computer') AS subject,
           DECODE(unpivot_row, 1, math,
                               2, science,
                               3, computer) AS percentage
    FROM tablea
    CROSS JOIN (SELECT level AS unpivot_row FROM dual CONNECT BY level <= 3)
)
GROUP BY subject
ORDER BY subject;

SUBJECT  PERCENTAGE
-------- ----------
Computer      94.33
Math          91.33
Science       87.33

在这两种情况下,内部 select 正在改变行成列; 在 10 g,你只需要做你自己。SELECT ... CONNECT BY ...只是生成的虚拟值列表,这必须要有足够支付的你都要转换为行的列数 (和如果你真的有 1000年,你真的应该重新审查数据模型)。这两个 decode 生成的编号,以匹配列名称和值-的语句使用运行内部选择自己到 se 什么看起来像。

而不是诉诸动态 SQL,你不能否认不必列出的列-只有一次真正的 unpivot ,但两次与假 10 g 版本,和你要确保他们正确,匹配了和行数发生器生产足够多的值。(太多,你可能会得到奇怪的结果,但作为任何额外的值将为 null 这里和你正在使用 avg ,在这种情况下它并不太重要; 只是作为一个检查您也许应使它无论如何完全匹配)。


或另一个版本,基于你总是想要除外的所有列 name ,这就意味着你只需要列出的列要做一次和它们匹配起来,视觉上 — — 就更容易保持添加 when 条款; 和你不需要的行数︰

SELECT subject, AVG(percentage) AS percentage
FROM (
    SELECT column_name AS subject,
        CASE
            WHEN column_name = 'MATH' then math
            WHEN column_name = 'SCIENCE' then science
            WHEN column_name = 'COMPUTER' then computer
        END AS percentage
    FROM tablea
    CROSS JOIN (
        SELECT column_name
        FROM user_tab_columns
        WHERE table_name = 'TABLEA'
        AND column_name != 'NAME'
    )
)
GROUP BY subject
ORDER BY subject;

SUBJECT                        PERCENTAGE
------------------------------ ----------
COMPUTER                            94.33
MATH                                91.33
SCIENCE                             87.33
官方微信
官方QQ群
31647020