Как получить все значения в одной строке без использования нескольких условий объединения в SQL? - PullRequest
0 голосов
/ 06 августа 2020

У меня есть структура таблицы ниже

Студент

Stud_ID | First_Name | Last_name | Contact
ID001   | AAA        | AAA       |     111
ID002   | BBB        | BBB       |     222

StudUser

Stud_ID | NUM | Value
ID001   |  10 | English
ID001   |  20 | Math
ID001   |  30 | Science
ID002   |  10 | English
ID002   |  20 | Math

Ожидаемый результат

Stud_id | First_name | 10      | 20    | 30
ID001   | AAA        | English | Math  | Science
ID002   | BBB        | English | Math  |

Текущий запрос, который я использую

select 
        stud_id,
        First_name,
        EG.EGUV AS "10",
        LE.LEUV AS "20",
        FPS.FPSUV AS "30"
from 
        student,
        (SELECT STUD_ID AS EGS,USER_VALUE AS EGUV FROM STUD_USER WHERE COL_NUM='10') AS EG,
        (SELECT STUD_ID AS BUS,USER_VALUE AS BUUV FROM STUD_USER WHERE COL_NUM='20') AS BU,
        (SELECT STUD_ID AS AUS,USER_VALUE AS AUV FROM STUD_USER WHERE COL_NUM='30') AS A
where
        ST.STUD_ID=EG.EGS(+) and 
        ST.STUD_ID=BU.BUS(+) and    
        ST.STUD_ID=A.AUS(+)

Сообщите мне, есть ли другой оптимизированный способ получить все пользовательские значения. Примечание: эту структуру таблицы нельзя изменить, доступно только разрешение на чтение

1 Ответ

0 голосов
/ 11 августа 2020

Для этого можно использовать предложение Oracle PIVOT . Он будет ( тип ) динамически создавать дополнительные столбцы в соответствии со значениями выбранного столбца.

Это тот запрос, который я использовал (используя предложения WITH для имитации вашего ввода data):

WITH
Student
AS
    (SELECT 'ID001' AS Stud_ID, 'AAA' AS First_Name, 'AAA' AS Last_name, 111 AS Contact FROM DUAL
     UNION ALL
     SELECT 'ID002', 'BBB', 'BBB', 222 FROM DUAL),
StudUser
AS
    (SELECT 'ID001' AS Stud_ID, 10 AS NUM, 'English' AS VALUE FROM DUAL
     UNION ALL
     SELECT 'ID001', 20, 'Math' FROM DUAL
     UNION ALL
     SELECT 'ID001', 30, 'Science' FROM DUAL
     UNION ALL
     SELECT 'ID002', 10, 'English' FROM DUAL
     UNION ALL
     SELECT 'ID002', 20, 'Math' FROM DUAL),
Prepare
AS
    (SELECT ST.STUD_ID,
            ST.FIRST_NAME,
            SU.NUM,
            SU.VALUE
       FROM STUDENT ST LEFT JOIN STUDUSER SU ON ST.STUD_ID = SU.STUD_ID)
SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN (10, 20, 30))

Функция PIVOT ожидает агрегатную функцию, потому что она будет go по всем результатам, где, например, STUD_ID = ID001 and NUM = 10, и вернет значение в соответствии с агрегатная функция, которая использовалась. Ваш пример подразумевает, что комбинация STUD_ID and NUM будет уникальной для таблицы StudUser , поэтому большинство агрегатных функций Oracle подойдут, так как они должны будут go иметь только одно значение. Если бы комбинация не была уникальной, вам пришлось бы на секунду подумать о том, как бы вы хотели их объединить.

Раздел FOR в pivot * 1025 Предложение * позволяет указать, какие значения вы хотите преобразовать в столбцы. Это, к сожалению, не может быть сгенерировано динамически, например:

SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN ( SELECT DISTINCT NUM FROM StudUser ))

Это будет недопустимым и не будет компилироваться.

Вы также можете указать желаемые имена столбцов для сводные столбцы, например:

SELECT *
FROM Prepare PIVOT (MIN (VALUE) FOR NUM IN (10 Subject1, 20 Subject2, 30 Subject3))

Я нашел предложение PIVOT , просто выполнив поиск: oracle превратить значения в столбцы , так что я как бы догадываюсь, что вы не Не нашел, потому что не знал, как это назвать. Не могу винить вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...