SQL показывает столбец на основе значений столбца другой таблицы

ORACLE SQL с моим полу-начинающим опытом.

У меня есть таблица Credits по одной строке на идентификатор:

ID, ArtCred, BizCred, HumCred, NatCred, TekCred, GenCred
5001, 12, 7.5, 12, 14, 11, 9
5002, 10.5, 6, 5, 4, 6, 3

с идентификатором для каждого студента и кредитами для каждой группы курса.

Учащиеся могут выбрать группу (группы) курса, на которой они сосредоточатся, из таблицы GrpChoice, в которой указан их выбор и дата, когда они его сделали.

ID, GroupChoice, DateChoice
5001, ART, 3/3/2010
5001, BIZ, 5/5/2015
5001, NAT, 6/23/2022
5002, ART, 6/23/2023

Я могу запросить кредиты каждой группы для каждого студента, даже если он не выбран):

SELECT
    ID,
    GroupChoice, 
    artcred,
    bizcred,
    humcred,
    natcred,
    tekcred,
    gencred
FROM 
    Grpchoice
INNER JOIN 
    Credits ON GrpChoice.ID = Credits.ID
ORDER BY 
    Grpchoice.datechoice Desc
ID   Group   Art     Biz     Hum     Nat    Tek     Gen
5001  TEK   12  7.5 12  14  11  9
5001  HHS   12  7.5 12  14  11  9
5001  BIZ   12  7.5 12  14  11  9
5001  ART   12  7.5 12  14  11  9
5002  ART       10.5     6       5       4       6      3 

но мне нужно показать для каждого идентификатора и кредитов, полученных для GrpChoice (отсортировать по дате desc):

Я хочу видеть только для ID 5001:

 ART 12
 BIZ 7.5
 NAT 14

Для идентификатора 5002:

 ART 10.5

Я пробовал PIVOT, но, поскольку значение GrpChoice может измениться, я не думаю, что смогу его использовать. Если я не настрою свои данные по-другому для поворота по идентификатору... Я только читал о поворотах.

CASE GRPCHOICE не будет работать, потому что он не изменит SELECT на основе его значения (я не могу «SELECT CASE When GrpChoice = "Art", затем SELECT artCHr, WHEN GrpChoice="BIZ", затем SELECT bizCHr...") .

Я просмотрел OVER (PARTITION BY), но не понимаю, как это будет работать.

Предложения приветствуются, спасибо.

Проблема в дизайне базы данных. В таблице GrpChoice ART, BIZ, NAT и т.д. есть данные. В таблице Credits есть структура (ArtCred, BizCred и т.д.). Решите, должны ли эти темы быть частью структуры базы данных или просто данными в базе данных. Не смешивайте это. Я предлагаю сделать темы данными, чтобы вы могли легко добавить тему или удалить тему в любое время. Это означает, что вы должны изменить таблицу Credits, чтобы она имела три столбца: идентификатор студента, предмет и кредит.

Thorsten Kettner 13.04.2023 23:03

В своем ответе MT0 показывает, как преобразовать таблицу кредитов на лету. Но было бы лучше изменить таблицу в базе данных, чтобы запрос не должен был знать, какие субъекты существуют в базе данных.

Thorsten Kettner 13.04.2023 23:04

Есть два набора данных. Выбор группы - это имя группы в качестве данных. Затем кредиты, полученные для каждой группы, представляют собой данные с именем группы в качестве имени субъекта / поля. Группы постоянны, и каждая группа имеет кредитное значение. Но выбор может меняться и иметь несколько значений с течением времени.

bikewimp 14.04.2023 14:47
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте UNPIVOT вместо PIVOT, а затем соедините две таблицы:

SELECT c.id, subject, credit
FROM   credits
       UNPIVOT (
         credit FOR subject IN (
           artcred As 'ART',
           bizcred AS 'BIZ',
           humcred AS 'HUM',
           natcred AS 'NAT',
           tekcred AS 'TEK',
           gencred AS 'GEN'
         )
       ) c
       INNER JOIN grpchoice g
       ON c.id = g.id AND c.subject = g.groupchoice

Что для примера данных:

CREATE TABLE credits (ID, ArtCred, BizCred, HumCred, NatCred, TekCred, GenCred) AS
SELECT 5001, 12, 7.5, 12, 14, 11, 9 FROM DUAL UNION ALL
SELECT 5002, 10.5, 6, 5, 4, 6, 3 FROM DUAL;

CREATE TABLE GrpChoice (ID, GroupChoice, DateChoice) AS
SELECT 5001, 'ART', DATE '2010-03-03' FROM DUAL UNION ALL
SELECT 5001, 'BIZ', DATE '2015-05-05' FROM DUAL UNION ALL
SELECT 5001, 'NAT', DATE '2022-06-23' FROM DUAL UNION ALL
SELECT 5002, 'ART', DATE '2023-06-23' FROM DUAL;

Выходы:

ИДЕНТИФИКАТОР ПРЕДМЕТ КРЕДИТ 5001 ИСКУССТВО 12 5001 БИЗ 7,5 5001 NAT 14 5002 ИСКУССТВО 10,5

рабочий пример

Интересный. Я бы никогда не догадался, что существует заявление UNPIVOT. Такой результат выглядит идеально.

bikewimp 14.04.2023 14:40
Ответ принят как подходящий

На самом деле, с предоставленными образцами данных вы можете использовать выражение CASE для получения ожидаемого результата:

WITH        --  Sample Data
    credits AS
        (
            Select 5001 "ID", 12 "ARTCRED", 7.5 "BIZCRED", 12 "HUMCRED", 14 "NATCRED", 11 "TEKCRED", 9 "GENCRED" From Dual Union All
            Select 5002 "ID", 10.5 "ARTCRED", 6 "BIZCRED",  5 "HUMCRED",  4 "NATCRED",  6 "TEKCRED", 3 "GENCRED" From Dual 
        ),
    grp_choices AS
        (
            Select 5001 "ID", 'ART' "GROUPCHOICE", To_Date('03.03.2010', 'dd.mm.yyyy') "DATECHOICE" From Dual Union All
            Select 5001 "ID", 'BIZ' "GROUPCHOICE", To_Date('05.05.2015', 'dd.mm.yyyy') "DATECHOICE" From Dual Union All
            Select 5001 "ID", 'NAT' "GROUPCHOICE", To_Date('23.06.2022', 'dd.mm.yyyy') "DATECHOICE" From Dual Union All
            Select 5002 "ID", 'ART' "GROUPCHOICE", To_Date('23.06.2023', 'dd.mm.yyyy') "DATECHOICE" From Dual
        )
--
--  M a i n   S Q L
Select  c.ID, 
        g.GROUPCHOICE, 
        CASE g.GROUPCHOICE
            WHEN 'ART' THEN c.ARTCRED
            WHEN 'BIZ' THEN c.BIZCRED
            WHEN 'HUM' THEN c.HUMCRED
            WHEN 'NAT' THEN c.NATCRED
            WHEN 'TEK' THEN c.TEKCRED
            WHEN 'GEN' THEN c.GENCRED
        ELSE 0
        END "CREDIT"
From    credits c
Inner Join grp_choices g ON(g.ID = c.ID)
--
--  R e s u l t :
        ID GROUP     CREDIT
---------- ----- ----------
      5001 ART           12
      5001 BIZ          7.5
      5001 NAT           14
      5002 ART         10.5

Вот почему я спросил. Я знал, что должен быть простой способ расколоть этот орех. Спасибо.

bikewimp 14.04.2023 15:58

Другие вопросы по теме