【问题标题】:Convert rows to columns on Oracle 11g在 Oracle 11g 上将行转换为列
【发布时间】:2019-01-18 17:09:53
【问题描述】:

我有一个包含两列(姓名和性别)的表格。我的表中有 4 条记录。

Name  Gender
A       Male
B       Female
C       Male
D       Female

我想写一个 SQL 查询来把上面的数据转换成下面的格式。

Male      Female
A           B    
C           D

【问题讨论】:

  • 为什么要匹配不相关的数据?
  • 您能详细解释一下预期结果吗?输出的逻辑是A-B 而不是A-D?如果我们还有 1 (2, 3, ...) 行,例如 E Female,预期的输出是什么?

标签: sql oracle


【解决方案1】:

另一种类似于 Tim 的可能性,但只需要一个 CTE:

with numbered as (
   select name, gender, row_number() over (partition by gender order by name) as rn
   from the_table
)
select f.name as "Female", m.name as "Male"
from numbered f 
  full outer join numbered m on m.rn = f.rn and m.gender = 'Male'
where f.gender = 'Female';

如果每个性别有不同的行数,也可以使用完全外连接。

Online example

【讨论】:

  • 但是每个人有多性别呢:P?
  • @TimBiegeleisen:这不会改变输出中的任何内容。该查询仅考虑男性和女性。如果碰巧有更多的性别,那些会在窗口函数中生成额外的分区,由于连接条件和位置中的过滤器,这些分区根本不会被使用。 dbfiddle.uk/…
  • 我在那条评论中开了个玩笑。你的回答很好。
【解决方案2】:

这是一种选择,使用 CTE:

WITH male AS (
    SELECT Name, ROW_NUMBER() OVER (ORDER BY Name) rn
    FROM yourTable
    WHERE Gender = 'Male'
),
female AS (
    SELECT Name, ROW_NUMBER() OVER (ORDER BY Name) rn
    FROM yourTable
    WHERE Gender = 'Female'
)

SELECT m.Name AS Male, f.Name AS Female
FROM male m
INNER JOIN female f
    ON m.rn = f.rn;

Demo

【讨论】:

    【解决方案3】:

    可能就这么简单:

    SELECT m.Name Male, f.Name Female
    FROM t m, t f
    WHERE m.Gender = "Male" AND f.Gender = "Female";
    

    但这没有多大意义,我希望你知道你在做什么。

    【讨论】:

    • 您好,感谢您的回复。这让我接近我的答案,除了 4 行而不是 2 行。我看到 2 个正确的行和 2 个不正确的行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多