oracle 如何根据不同的值为列编写SQL?

k97glaaz  于 2023-10-16  发布在  Oracle
关注(0)|答案(3)|浏览(121)

我有一个下表
| 列A|色谱柱B|
| --|--|
| 1000 | 8800 |
| 1000 | 8810 |
| 1000 | 8820 |
| 2000 | 9900 |
| 2000 | 9910 |
我需要创建一个列为C的下表。列C包含来自列B的值,列A具有该值的公共值。例如:对于1000,有3个值8800,8810,8820。因此,对于1000和B列值的每个组合,我需要C列中的剩余值。如何使用SQL生成下表?
| 列A|色谱柱B|列C|
| --|--|--|
| 1000 | 8800 | 8810 |
| 1000 | 8800 | 8820 |
| 1000 | 8810 | 8800 |
| 1000 | 8810 | 8820 |
| 1000 | 8820 | 8800 |
| 1000 | 8820 | 8810 |
| 2000 | 9900 | 9910 |
| 2000 | 9910 | 9900 |
| | | |
| | | |
我尝试使用Concat,但无法生成列c

kx1ctssn

kx1ctssn1#

一个选项是执行自联接。
示例数据:

SQL> with test (cola, colb) as
  2    (select 1000, 8800 from dual union all
  3     select 1000, 8810 from dual union all
  4     select 1000, 8820 from dual union all
  5     --
  6     select 2000, 9900 from dual union all
  7     select 2000, 9910 from dual
  8    )

查询方式:

9  select a.cola, a.colb, b.colb colc
 10  from test a join test b on a.cola = b.cola and b.colb not in (a.cola, a.colb)
 11  order by a.cola, a.colb, b.colb;

      COLA       COLB       COLC
---------- ---------- ----------
      1000       8800       8810
      1000       8800       8820
      1000       8810       8800
      1000       8810       8820
      1000       8820       8800
      1000       8820       8810
      2000       9900       9910
      2000       9910       9900

8 rows selected.

SQL>
zpqajqem

zpqajqem2#

您可以使用分层查询来消除对任何联接的需要:

SELECT cola,
       PRIOR colb AS colb,
       colb AS colc
FROM   table_name
WHERE  LEVEL = 2
CONNECT BY NOCYCLE
       PRIOR cola = cola
AND    PRIOR colb <> colb;

其中,对于样本数据:

CREATE TABLE table_name (cola, colb) AS
  SELECT 1000, 8800 FROM DUAL UNION ALL
  SELECT 1000, 8810 FROM DUAL UNION ALL
  SELECT 1000, 8820 FROM DUAL UNION ALL
  SELECT 2000, 9900 FROM DUAL UNION ALL
  SELECT 2000, 9910 FROM DUAL;

输出:
| 可乐|COLB| COLC|
| --|--|--|
| 1000 | 8800 | 8810 |
| 1000 | 8800 | 8820 |
| 1000 | 8810 | 8800 |
| 1000 | 8810 | 8820 |
| 1000 | 8820 | 8800 |
| 1000 | 8820 | 8810 |
| 2000 | 9900 | 9910 |
| 2000 | 9910 | 9900 |
fiddle

zzwlnbp8

zzwlnbp83#

您可以将所有值聚合到每个组的集合中(column_a值),然后执行此集合与其自身的交叉联接以生成所有对。

with agg as (
  select
    column_a,
    collect(column_b) as vals
  from sample
  group by column_a
)
select
  column_a,
  column_b.column_value as column_b,
  column_c.column_value as column_c
from agg
  cross join table(vals) column_b
  cross join table(vals) column_c
where column_b.column_value != column_c.column_value

它为您的数据生成以下输出:
| 列_A|列_B| C列|
| --|--|--|
| 1000 | 8800 | 8820 |
| 1000 | 8800 | 8810 |
| 1000 | 8820 | 8800 |
| 1000 | 8820 | 8810 |
| 1000 | 8810 | 8800 |
| 1000 | 8810 | 8820 |
| 2000 | 9900 | 9910 |
| 2000 | 9910 | 9900 |
fiddle

相关问题