Oracle SQL - транспонировать столбец в группу строк - PullRequest
1 голос
/ 06 мая 2019

У меня следующий SQL-запрос, работающий с экземпляром Oracle 11g, который прекрасно работает:

SELECT
    TRIM(PART_NM) || TRIM(PART_NO),
    TRIM(MKBY_IND),
    MFG_TYP

FROM
    TblPARTS

WHERE
    ORDER_START_DATE >= (SYSDATE - 365)
    AND
    TO_CHAR(TRIM(PART_NO)) != '99'

Что дает следующие результаты:

| Part | Make / Buy |    Area   |
|:----:|:----------:|:---------:|
| AU54 |      M     |    Demo   |
| ZA45 |      M     | Construct |
| AD28 |      B     | Construct |
| SX73 |      B     | Construct |
| MO47 |      M     | Construct |
| IN66 |      B     | Construct |
| RP42 |      M     |    Demo   |
| HF77 |      B     |    Demo   |
| IE43 |      B     |  Personal |
| OX11 |      B     |  Personal |
| ZE45 |      M     |    Demo   |
| JH21 |      M     | Construct |
| AM91 |      M     | Construct |
| DS50 |      M     |    Demo   |
| LE29 |      M     |    Demo   |
| IP91 |      M     |    Demo   |
| ID42 |      M     |    Demo   |
| RI96 |      M     |    Demo   |

У меня там нет проблем. Тем не менее, мне было предложено транспонировать столбец Площадь и вместо этого сгруппировать строки по нему. Что-то похожее на:

|    Part   | Make / Buy |
|:---------:|:----------:|
| CONSTRUCT |  CONSTRUCT |
|    AU54   |      M     |
|    ZA45   |      M     |
|    AD28   |      B     |
|    SX73   |      M     |
|    MO47   |      M     |
|    IN66   |      B     |
|    JH21   |      M     |
|    AM91   |      B     |
|    DEMO   |    DEMO    |
|    RP42   |      M     |
|    HF77   |      M     |
|    ZE45   |      M     |
|    DS50   |      B     |
|    LE29   |      M     |
|    IP91   |      M     |
|    ID42   |      M     |
|    RI96   |      M     |
|  PERSONAL |  PERSONAL  |
|    IE43   |      M     |
|    OX11   |      M     |

Короче говоря, я ищу, чтобы найти уникальные значения в поле столбца "Площадь" (MFG_TYP) и иметь возможность группировать их по ряду. Следует отметить, что три перечисленные записи действительны в моем наборе данных, но могут быть изменены, поэтому я не ищу статическое решение, а вместо этого способ динамического применения преобразования ко всем уникальным значениям в столбце Area .

Я пытался просмотреть эти ресурсы, но в настоящее время не не понимает, как создать решение. Любой совет приветствуется.

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Быстрое решение с расширением ROLLUP для GROUP BY :

with
  TblPARTS(Part, Make_Buy, Area) as (
    select 'AU54', 'M', 'Demo' from dual union all
    select 'ZA45', 'M', 'Construct' from dual union all
    select 'AD28', 'B', 'Construct' from dual union all
    select 'SX73', 'B', 'Construct' from dual union all
    select 'MO47', 'M', 'Construct' from dual union all
    select 'IN66', 'B', 'Construct' from dual union all
    select 'RP42', 'M', 'Demo' from dual union all
    select 'HF77', 'B', 'Demo' from dual union all
    select 'IE43', 'B', 'Personal' from dual union all
    select 'OX11', 'B', 'Personal' from dual union all
    select 'ZE45', 'M', 'Demo' from dual union all
    select 'JH21', 'M', 'Construct' from dual union all
    select 'AM91', 'M', 'Construct' from dual union all
    select 'DS50', 'M', 'Demo' from dual union all
    select 'LE29', 'M', 'Demo' from dual union all
    select 'IP91', 'M', 'Demo' from dual union all
    select 'ID42', 'M', 'Demo' from dual union all
    select 'RI96', 'M', 'Demo' from dual union all
    select 'AO42', 'M', 'Public' from dual union all
    select 'OA42', 'B', 'Public' from dual
  ),
  a as (
    select
      Part, Make_Buy, Area,
      GROUPING_ID(Area, Part, Make_Buy) gid
    from TblPARTS
    group by rollup(Area, (Part, Make_Buy))
    having GROUPING_ID(Area, Part, Make_Buy) < 7
  )
select
  coalesce(Part, Area) Part,
  coalesce(Make_Buy, Area) Make_Buy
from a
order by Area, gid desc

Выход:

+------------+-----------+
|    PART    |  MAKE_BUY |
+------------+-----------+
| Construct  | Construct |
| AM91       | M         |
| IN66       | B         |
| JH21       | M         |
| SX73       | B         |
| ZA45       | M         |
| AD28       | B         |
| MO47       | M         |
| Demo       | Demo      |
| ZE45       | M         |
| RP42       | M         |
| RI96       | M         |
| LE29       | M         |
| IP91       | M         |
| ID42       | M         |
| HF77       | B         |
| AU54       | M         |
| DS50       | M         |
| Personal   | Personal  |
| OX11       | B         |
| IE43       | B         |
| Public     | Public    |
| OA42       | B         |
| AO42       | M         |
+------------+-----------+

Протестируйте его онлайн с помощью Rextester .

0 голосов
/ 06 мая 2019

Похоже, это то, что вы ищете:

SELECT
    'CONSTRUCT' AS "Part",
    'CONSTRUCT' AS "Make / Buy"
FROM DUAL

UNION

SELECT
    TRIM(PART_NM) || TRIM(PART_NO) AS "Part",
    TRIM(MKBY_IND) AS "Make / Buy"
FROM
    TblPARTS
WHERE
    ORDER_START_DATE >= (SYSDATE - 365)
    AND    TO_CHAR(TRIM(PART_NO)) != '99'
    AND    MFG_TYP = 'Construct'

UNION

SELECT
    'DEMO' AS "Part",
    'DEMO' AS "Make / Buy"
FROM DUAL

UNION

SELECT
    TRIM(PART_NM) || TRIM(PART_NO) AS "Part",
    TRIM(MKBY_IND) AS "Make / Buy"
FROM
    TblPARTS
WHERE
    ORDER_START_DATE >= (SYSDATE - 365)
    AND    TO_CHAR(TRIM(PART_NO)) != '99'
    AND    MFG_TYP = 'Demo'

UNION

SELECT
    'PERSONAL ' AS "Part",
    'PERSONAL ' AS "Make / Buy"
FROM DUAL

UNION

SELECT
    TRIM(PART_NM) || TRIM(PART_NO)) AS "Part",
    TRIM(MKBY_IND) AS "Make / Buy"
FROM
    TblPARTS
WHERE
    ORDER_START_DATE >= (SYSDATE - 365)
    AND    TO_CHAR(TRIM(PART_NO)) != '99'
    AND    MFG_TYP = 'Personal'
...