如何从每一行中选择不同的列?

时间:2019-07-15 12:25:39

标签: sql oracle plsql

我有一个表,该表具有三列和三个记录。如何选择第一列的第一值,第二列的第二值,第三列的第三值?

table
============
test_tab

id1   id2   id2
===   ===   ====
100   400   700
200   500   800
300   600   900

必填输出,如:

100  500  900

如何使用Oracle SQL或PL / SQL实现此目标?

2 个答案:

答案 0 :(得分:1)

首先,您如何确定第一行是哪一行,第二行是哪一行?

Oracle不保证记录的顺序,必须使用order by子句显式地对其进行排序,否则它将是随机的(默认查询输出)

使用测试数据和结果,可以使用以下查询: 注意:我将第三列视为ID3,并使用ID1来对行进行排序

SELECT
    MAX(CASE RN
        WHEN 1   THEN ID1
    END) AS ID1,
    MAX(CASE RN
        WHEN 2   THEN ID2
    END) AS ID2,
    MAX(CASE RN
        WHEN 3   THEN ID3
    END) AS ID3
FROM
    (
        SELECT
            ID1,
            ID2,
            ID3,
            ROW_NUMBER() OVER(
                ORDER BY
                    ID1
            ) RN
        FROM
            TEST_TAB
    );

干杯!

答案 1 :(得分:0)

您将需要一种方法来确定“第一”的含义。 在Oracle中,这是解决您的问题示例的一种方法:

create table test_tab(
  id1 integer,
  id2 integer,
  id3 integer
);

insert into test_tab values(100,400,700);
insert into test_tab values(200,500,800);
insert into test_tab values(300,600,900);

commit;

select sum(decode(pos, 1, id1, null)) id1,
       sum(decode(pos, 2, id2, null)) id2,
       sum(decode(pos, 3, id3, null)) id3
  from(
    -- this subquery produces a rank column for the whole dataset
    -- with an explicit order
    select id1, id2, id3, rank() over (order by id1, id2, id3) pos from TEST_TAB
  );

在此实现中,子查询用于建立行的顺序,并基于pos函数添加新的rank()列。

sum(decode(pos, 3, id3, null))构造是Oracle的一种惯用法,用于选择一个特定的行(在本例中为第3行),而忽略其他行。 基本上,对于您的三行,decode将导致除具有指定编号的行以外的任何行的NULL,因此id3的表达式将仅具有非空值第三行,因此该组的总和将等于第3行中的id3

执行此操作的方法有很多,这只是其中一种,您可能需要对该实现进行一些调整,以使其在实际代码中正常工作。