在一种SQL中将行转换为列,但不影响数字行

时间:2018-09-11 06:41:55

标签: sql oracle

我有一张表,其结构和数据如下所示:
enter image description here

然后我要一个SQL像这样转换它:
enter image description here

我真的不知道如何编写SQL来完成此功能,有人可以帮助我吗?对于此类主题,我已经引用了很多以前的答案,但是找不到适合我的案例的答案。谁能帮我。

1 个答案:

答案 0 :(得分:1)

如果只考虑三个级别,则可以使用分层查询来实现:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name ( LineItem_Name, LineItem_Id, parent_id, dept_name, product_name ) AS
  SELECT 'ABC', 1, NULL, 'D1', 'P1' FROM DUAL UNION ALL
  SELECT 'CDF', 2,    1, 'D2', 'P2' FROM DUAL UNION ALL
  SELECT 'EFG', 3,    1, 'D3', 'P3' FROM DUAL UNION ALL
  SELECT 'HIJ', 4,    2, 'D4', 'P4' FROM DUAL;

查询1

SELECT CONNECT_BY_ROOT( LineItem_Name) AS LineItem_Level1,
       CASE LEVEL
       WHEN 3 THEN PRIOR LineItem_Name
       WHEN 2 THEN LineItem_Name
       END AS LineItem_Level2,
       CASE LEVEL
       WHEN 3 THEN LineItem_Name
       END AS LineItem_Level3,
       dept_name,
       product_name
FROM   table_name
START WITH parent_id IS NULL
CONNECT BY PRIOR LineItem_ID = parent_id

Results

| LINEITEM_LEVEL1 | LINEITEM_LEVEL2 | LINEITEM_LEVEL3 | DEPT_NAME | PRODUCT_NAME |
|-----------------|-----------------|-----------------|-----------|--------------|
|             ABC |          (null) |          (null) |        D1 |           P1 |
|             ABC |             CDF |          (null) |        D2 |           P2 |
|             ABC |             CDF |             HIJ |        D4 |           P4 |
|             ABC |             EFG |          (null) |        D3 |           P3 |

查询2 :这是使用递归子查询分解的一种选择,它将获取当前订单项的祖父母和父项;与上一个查询稍有不同,但是3个级别的查询结果相同。

WITH tree ( id, grandparent, parent, item, dept_name, product_name ) AS (
  SELECT LineItem_id,
         NULL,
         NULL,
         LineItem_name,
         dept_name,
         product_name
  FROM   table_name
  WHERE  parent_id IS NULL
UNION ALL
  SELECT t.lineItem_id,
         p.parent,
         p.item,
         t.lineItem_name,
         t.dept_name,
         t.product_name
  FROM   tree p
         INNER JOIN
         table_name t
         ON ( p.id = t.parent_id )
)
SELECT COALESCE( grandparent, parent, item ) AS LineItem_Level1,
       CASE
       WHEN parent IS NULL THEN NULL
       WHEN grandparent IS NULL THEN item
       ELSE parent
       END AS LineItem_Level2,
       NVL2( grandparent, item, NULL ) AS LineItem_Level3,
       dept_name,
       product_name
FROM   tree

Results

| LINEITEM_LEVEL1 | LINEITEM_LEVEL2 | LINEITEM_LEVEL3 | DEPT_NAME | PRODUCT_NAME |
|-----------------|-----------------|-----------------|-----------|--------------|
|             ABC |          (null) |          (null) |        D1 |           P1 |
|             ABC |             CDF |          (null) |        D2 |           P2 |
|             ABC |             EFG |          (null) |        D3 |           P3 |
|             ABC |             CDF |             HIJ |        D4 |           P4 |