Объединение трех таблиц, включающих в себя пункты where - PullRequest
0 голосов
/ 05 июля 2018

У меня есть следующий код:

SELECT KAYTTAJA.ti_ka_kayttajaid as USER_ID, 
       KAYTTAJA.ti_ka_etunimi as USER_NAME, 
       EXAM.ti_su_sitoumusid as SITOUMUS_ID, 
       EXAM.ti_su_nimitys as SITOUMUS_NAME, 
       PVM.ti_sk_paivamaara AS SITOUMUS_DATE
FROM ti_sitoumus_kayttaja PVM
    WHERE PVM.ti_sk_kayttajaid IN (
        SELECT DISTINCT ti_kayttajantyoyksikko.ti_kt_kayttajaid
        FROM ti_kayttajantyoyksikko 
        WHERE ti_kayttajantyoyksikko.ti_kt_tyoyksikko IN(
            SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
            FROM ti_esimiehentyoyksikko 
            WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784)) 
JOIN ti_kayttaja KAYTTAJA
    WHERE KAYTTAJA.ti_ka_kayttajaid IN (
        SELECT DISTINCT ti_kayttajantyoyksikko.ti_kt_kayttajaid
        FROM ti_kayttajantyoyksikko 
        WHERE ti_kayttajantyoyksikko.ti_kt_tyoyksikko IN(
            SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
            FROM ti_esimiehentyoyksikko 
            WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784))
ON PVM.ti_sk_kayttajaid(+) = KAYTTAJA.ti_ka_kayttajaid
JOIN FROM ti_sitoumus EXAM
    WHERE EXAM.ti_su_sitoumusid IN (
        SELECT DISTINCT ti_kayttooikeus_ryhma.ti_kr_kayttokohdeid
        FROM ti_kayttooikeus_ryhma 
        WHERE ti_kayttooikeus_ryhma.ti_kr_kayttokohde = 6 
        AND ti_kayttooikeus_ryhma.ti_kr_kohdeid IN (
            SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
            FROM ti_esimiehentyoyksikko 
            WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784))
ON PVM.ti_sk_sitoumusid = EXAM.ti_su_sitoumusid(+)
ORDER BY KAYTTAJA.ti_ka_kayttajaid;

Это дает мне сообщение об ошибке: «Команда SQL неправильно завершена». По крайней мере, первый JOIN не работает, и я не знаю, как это исправить. В конечном итоге я пытаюсь добиться этого: Используя Oracle, объедините три таблицы в одну с PIVOT , но мне нужно использовать какой-то синтаксис JOIN при соединении таблиц.

Ответы [ 4 ]

0 голосов
/ 05 июля 2018

Я не уверен, что здесь все правильно понял, но похоже, что движущей таблицей для запроса является TI_KAYTTAJA с двумя другими основными таблицами (TI_SITOUMUS_KAYTTAJA и TI_SITOUMUS), предоставляющими необязательные данные. Если это правильно, то следующий запрос должен дать вам то, что вы ищете:

WITH cteTYOYKSIKKO AS
  (SELECT DISTINCT te.TI_ET_TYOYKSIKKOID
     FROM TI_ESIMIEHENTYOYKSIKKO te
     WHERE te.TI_ET_KAYTTAJAID = 14784)
SELECT k.TI_KA_KAYTTAJAID AS USER_ID, 
       k.TI_KA_ETUNIMI AS USER_NAME, 
       exam.TI_SU_SITOUMUSID AS SITOUMUS_ID, 
       exam.TI_SU_NIMITYS AS SITOUMUS_NAME, 
       pvm.TI_SK_PAIVAMAARA AS SITOUMUS_DATE
  FROM TI_KAYTTAJA k
  LEFT OUTER JOIN TI_SITOUMUS_KAYTTAJA pvm
    ON pvm.TI_SK_KAYTTAJAID = k.TI_KA_KAYTTAJAID AND
       pvm.TI_SK_KAYTTAJAID IN (SELECT DISTINCT tkt.TI_KT_KAYTTAJAID
                                  FROM TI_KAYTTAJANTYOYKSIKKO tkt
                                  INNER JOIN cteTYOYKSIKKO c
                                    ON c.TI_ET_TYOYKSIKKOID = tkt.TI_KT_TYOYKSIKKO
  LEFT OUTER JOIN TI_SITOUMUS exam
    ON exam.TI_SU_SITOUMUSID = pvm.TI_SK_SITOUMUSID AND
       exam.TI_SU_SITOUMUSID IN (SELECT DISTINCT tkr.TI_KR_KAYTTOKOHDEID
                                   FROM TI_KAYTTOOIKEUS_RYHMA tkr
                                   INNER JOIN cteTYOYKSIKKO c
                                     ON c.TI_ET_TYOYKSIKKOID = tkr.TI_KR_KOHDEID
                                   WHERE tkr.TI_KR_KAYTTOKOHDE = 6)
  WHERE k.TI_KA_KAYTTAJAID IN (SELECT DISTINCT tk.TI_KT_KAYTTAJAID
                                 FROM TI_KAYTTAJANTYOYKSIKKO tk
                                 INNER JOIN cteTYOYKSIKKO c
                                   ON c.TI_ET_TYOYKSIKKOID = tk.TI_KT_TYOYKSIKKO)
  ORDER BY k.TI_KA_KAYTTAJAID

Вышеприведенное предполагает, что данные, извлеченные из TI_SITOUMUS_KAYTTAJA и TI_SITOUMUS, являются необязательными в запросе, основываясь на наличии квалификаторов (+) в исходном запросе. Если это неверно для одной или обеих этих таблиц, тип соединения должен быть изменен с LEFT OUTER JOIN на INNER JOIN.

Удачи.

0 голосов
/ 05 июля 2018

Переместите все предложения where в конец запроса, чтобы это было что-то вроде

SELECT KAYTTAJA.ti_ka_kayttajaid as USER_ID, KAYTTAJA.ti_ka_etunimi as USER_NAME, EXAM.ti_su_sitoumusid as SITOUMUS_ID, EXAM.ti_su_nimitys as SITOUMUS_NAME, PVM.ti_sk_paivamaara AS SITOUMUS_DATE
FROM ti_sitoumus_kayttaja PVM
left JOIN ti_kayttaja KAYTTAJA ON PVM.ti_sk_kayttajaid = KAYTTAJA.ti_ka_kayttajaid
left JOIN FROM ti_sitoumus EXAM ON PVM.ti_sk_sitoumusid = EXAM.ti_su_sitoumusid

WHERE PVM.ti_sk_kayttajaid IN (
    SELECT DISTINCT ti_kayttajantyoyksikko.ti_kt_kayttajaid
    FROM ti_kayttajantyoyksikko 
    WHERE ti_kayttajantyoyksikko.ti_kt_tyoyksikko IN(
        SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
        FROM ti_esimiehentyoyksikko 
        WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784)) 

and KAYTTAJA.ti_ka_kayttajaid IN (
    SELECT DISTINCT ti_kayttajantyoyksikko.ti_kt_kayttajaid
    FROM ti_kayttajantyoyksikko 
    WHERE ti_kayttajantyoyksikko.ti_kt_tyoyksikko IN(
        SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
        FROM ti_esimiehentyoyksikko 
        WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784))


and EXAM.ti_su_sitoumusid IN (
    SELECT DISTINCT ti_kayttooikeus_ryhma.ti_kr_kayttokohdeid
    FROM ti_kayttooikeus_ryhma 
    WHERE ti_kayttooikeus_ryhma.ti_kr_kayttokohde = 6 
    AND ti_kayttooikeus_ryhma.ti_kr_kohdeid IN (
        SELECT DISTINCT ti_esimiehentyoyksikko.ti_et_tyoyksikkoid
        FROM ti_esimiehentyoyksikko 
        WHERE ti_esimiehentyoyksikko.ti_et_kayttajaid=14784))

ORDER BY KAYTTAJA.ti_ka_kayttajaid;

Кстати, вы не можете использовать (+) с ANSI JOINS, если вы хотите использовать ANSI JOINS, используйте LEFT JOIN и RIGHT JOIN вместо (+).

0 голосов
/ 05 июля 2018

У вас есть три варианта объединения таблиц с предложениями WHERE:

1 Присоединитесь к таблицам и поставьте все предложения where в конце (как ответил @Amir Pashazadeh.

SELECT *
 FROM table1 JOIN table2 
WHERE conditions_on_table1
  AND conditions_on_table2 ...

2 Присоединиться к подзапросам, включая условия

SELECT *
 FROM table1
 JOIN (SELECT columns_I_need
        FROM table2
       WHERE conditions_on_table2)
   ON table1.col = table2.col

3 Используйте предложение WITH, чтобы разбить запрос на биты, которые легче понять (и проверить).

Я бы обычно использовал вариант 3 для такого запроса. Похоже, вы используете таблицы ti_kayttajantyoyksikko и ti_esimiehentyoyksikko дважды, поэтому я вставлю их в подзапрос:

WITH 
  my_unit AS (
    SELECT t1.ti_kt_kayttajaid AS USER_ID
      FROM ti_kayttajantyoyksikko t1
      JOIN ti_esimiehentyoyksikko t2
        ON t1.ti_kt_tyoyksikko = t2.ti_et_tyoyksikkoid
      WHERE t2.ti_et_kayttajaid = 14794)
SELECT * FROM my_unit;

Как только это сделает то, что я ожидаю, я добавлю следующую часть:

WITH 
  my_unit AS (
    SELECT t1.ti_kt_kayttajaid AS USER_ID
      FROM ti_kayttajantyoyksikko t1
      JOIN ti_esimiehentyoyksikko t2
        ON t1.ti_kt_tyoyksikko = t2.ti_et_tyoyksikkoid
      WHERE t2.ti_et_kayttajaid = 14794),
  my_users AS (
    SELECT k.ti_ka_kayttajaid as USER_ID
           k.ti_ka_etunimi    as USER_NAME
      FROM ti_kayttaja k
      JOIN my_unit u ON k.ti_ka_kayttajaid = u.user_id)
SELECT * FROM my_users;

... тогда ...

WITH 
  my_unit AS (
    SELECT t1.ti_kt_kayttajaid AS USER_ID
      FROM ti_kayttajantyoyksikko t1
      JOIN ti_esimiehentyoyksikko t2
        ON t1.ti_kt_tyoyksikko = t2.ti_et_tyoyksikkoid
      WHERE t2.ti_et_kayttajaid = 14794),
  my_users AS (
    SELECT k.ti_ka_kayttajaid as USER_ID
           k.ti_ka_etunimi    as USER_NAME
      FROM ti_kayttaja k
      JOIN my_unit u ON k.ti_ka_kayttajaid = u.user_id)
  my_pvm AS (
    SELECT PVM.PVM.ti_sk_kayttajaid AS USER_ID
           PVM.ti_sk_paivamaara     AS SITOUMUS_DATE
      FROM ti_sitoumus_kayttaja PVM
      JOIN my_unit u ON k.ti_kt_tyoyksikko = u.user_id)
SELECT * 
  FROM      my_users 
  LEFT JOIN my_pvm USING (user_id);

... и наконец ...

WITH 
  my_unit AS (
    SELECT t1.ti_kt_kayttajaid AS USER_ID
      FROM ti_kayttajantyoyksikko t1
      JOIN ti_esimiehentyoyksikko t2
        ON t1.ti_kt_tyoyksikko = t2.ti_et_tyoyksikkoid
      WHERE t2.ti_et_kayttajaid = 14794),
  my_users AS (
    SELECT k.ti_ka_kayttajaid as USER_ID
           k.ti_ka_etunimi    as USER_NAME
      FROM ti_kayttaja k
      JOIN my_unit u ON k.ti_ka_kayttajaid = u.user_id)
  my_pvm AS (
    SELECT PVM.PVM.ti_sk_kayttajaid AS USER_ID
           PVM.ti_sk_paivamaara     AS SITOUMUS_DATE,
           PVM.ti_sk_sitoumusid     AS SITOUMUS_ID
      FROM ti_sitoumus_kayttaja PVM
      JOIN my_unit u ON k.ti_kt_tyoyksikko = u.user_id),
  my_exam AS (
    SELECT EXAM.ti_su_sitoumusid as SITOUMUS_ID, 
           EXAM.ti_su_nimitys    as SITOUMUS_NAME
      FROM ti_sitoumus EXAM
     WHERE EXISTS (
             SELECT *
               FROM ti_kayttooikeus_ryhma t3
               JOIN ti_esimiehentyoyksikko t4
                 ON t3.ti_kr_kohdeid = t4.ti_et_tyoyksikkoid
              WHERE t3.ti_kr_kayttokohde = 6
                AND t4.ti_et_kayttajaid = 14784
                AND EXAM.ti_su_sitoumusid = t3.ti_kr_kayttokohdeid))
SELECT user_id, user_name, sitoumus_id, sitoumus_name, sitoumus_date
  FROM my_users 
  LEFT JOIN my_pvm  USING (user_id)
  LEFT JOIN my_exam USING (sitoumus_id)
 ORDER BY user_id;
0 голосов
/ 05 июля 2018

Много вопросов в вашем запросе. Вам необходимо:

SELECT
FROM table1, table2, table3   -- since you're using (+)
WHERE table2.joinKeyTable1 (+) = table1.joinKeyTable2
AND   table3.joinKeyTable1 (+) = table1.joinKeyTable3
AND <all filters>

Примечание. Поскольку это внешнее объединение - как вам кажется, вам нужно иметь (+) рядом с любым столбцом table2 и table3 во всех фильтрах: Пример:

AND table2.columnX (+) IN (...)

или

AND table3.columnY (+) = ...

При этом будут извлечены все записи таблицы table1, которые не имеют соответствующих (дочерних элементов) в таблице table2 или table3, независимо от фильтров, установленных в соответствующих столбцах table2 / table3

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