Несколько самостоятельных соединений плюс одно внутреннее соединение

У меня есть две таблицы: ck_startup и ck_price. Таблица цен содержит столбцы cu_type, prd_type, part_cd, qty и dllrs. Таблица запуска связана с таблицей цен через отношение «один ко многим» на ck_startup.prd_type_cd = ck_price.prd_type.

Таблица цен содержит несколько записей для одного и того же продукта / детали / количества, но для разных типов клиентов. Не все типы клиентов имеют одинаковую уникальную комбинацию этих трех значений. Я пытаюсь создать запрос, который будет делать две вещи:

  1. Присоедините несколько столбцов от ck_startup к ck_price (описание и некоторые дополнительные значения).
  2. Присоединитесь к ck_price с помощью столбца dllrs для каждого типа клиентов. Таким образом, у меня будет только один экземпляр каждого уникального ключа product / part / qty и значение в столбце цены каждого клиента, если оно у них есть.

Я никогда не работал с самосоединяющимися таблицами, и до сих пор я могу получать записи только в тех случаях, когда у обоих клиентов есть одинаковые варианты.

И поскольку кто-то потребует, чтобы я разместил образец кода, вот дерьмовый запрос, который не показывает отсутствующие цены:

select pa.*, pac.dllrs from ck_price pa
join ck_price pac on pa.prd_type = pac.prd_type and pa.part_carbon_cd = pac.part_carbon_cd and pa.qty = pac.qty
where pa.cu_type = 'A' and pac.cu_type = 'AC';

РЕДАКТИРОВАТЬ: Вот образцы данных из двух таблиц и то, как я хочу, чтобы они выглядели, когда я закончу:

CK_STARTUP
+-----+-----------------+-------------+
| CD  |       DSC       | PRD_TYPE_CD |
+-----+-----------------+-------------+
| 3D  | Stuff           | SKD3        |
| DC  | Different stuff | SKD         |
| DN2 | Similar stuff   | SKD         |
+-----+-----------------+-------------+

CK_PRICE
+---------+-------------+---------+-----+-------+
| CU_TYPE | PRD_TYPE_CD | PART_CD | QTY | DLLRS |
+---------+-------------+---------+-----+-------+
| A       | SKD3        |       1 | 100 |    10 |
| A       | SKD3        |       1 | 200 |    20 |
| A       | SKD3        |       1 | 300 |    30 |
| A       | SKD         |       1 | 100 |    50 |
| A       | SKD         |       1 | 200 |   100 |
| AC      | SKD3        |       1 | 300 |    30 |
| AC      | SKD         |       1 | 100 |   100 |
| AC      | SKD         |       1 | 200 |   200 |
| AC      | SKD         |       1 | 300 |   300 |
| AC      | SKD         |       1 | 400 |   400 |
+---------+-------------+---------+-----+-------+

COMBO:
+----+-----------------+---------+-----+---------+----------+
| CD |       DSC       | PART_CD | QTY | DLLRS_A | DLLRS_AC |
+----+-----------------+---------+-----+---------+----------+
| 3D | Stuff           |       1 | 100 | 10      | null     |
| 3D | Stuff           |       1 | 200 | 20      | null     |
| 3D | Stuff           |       1 | 300 | 30      | 60       |
| DC | Different stuff |       1 | 100 | 50      | 100      |
| DC | Different stuff |       1 | 200 | 100     | 200      |
| DC | Different stuff |       1 | 300 | null    | 300      |
| DC | Different stuff |       1 | 400 | null    | 400      |
+----+-----------------+---------+-----+---------+----------+

person Logarr    schedule 04.11.2013    source источник
comment
Есть ли в ORacle полное внешнее соединение?   -  person HLGEM    schedule 04.11.2013
comment
Да. Никогда не использовал. РЕДАКТИРОВАТЬ: переключение этого запроса на полное внешнее соединение не меняет набор результатов. Для справки: 423 записи в категории «A» и 384 записи в категории «AC». Набор результатов - 312 записей.   -  person Logarr    schedule 04.11.2013
comment
попробуйте добавить условия where к включенному   -  person HLGEM    schedule 04.11.2013
comment
Хм ... нет. Получение 11528 записей обратно. Это в основном размер таблицы в квадрате.   -  person Logarr    schedule 04.11.2013
comment
Трудно понять, что вы ожидаете от запроса. Не могли бы вы предоставить образцы данных из обеих таблиц и показать нам, каких результатов вы ожидаете?   -  person Przemyslaw Kruglej    schedule 05.11.2013
comment
@PrzemyslawKruglej - Добавлены примеры таблиц. Я в основном пытаюсь получить ценовую сетку из одного набора данных столбца. Присоединение стартовой таблицы к таблице цен менее важно, чем получение самостоятельных присоединений к таблице цен.   -  person Logarr    schedule 05.11.2013
comment
@Logarr, сколько разных значений у вас есть в столбце CU_TYPE в CU_PRICE таблице? Это может измениться? Если это так, то то, что вы пытаетесь достичь, невозможно, поскольку у вас будет неизвестное количество столбцов. PIVOT тоже не поможет, так как для него нужно предоставить статический список значений.   -  person Przemyslaw Kruglej    schedule 05.11.2013
comment
Возможные значения для CU_TYPE изменяются, только если я сам внесу изменения. Это будет выполняться вручную в SQL Developer, поэтому, если параметры для CU_TYPE изменятся, я готов внести изменения в свои объединения, чтобы отразить это.   -  person Logarr    schedule 05.11.2013
comment
Если у вас есть секунда, и вы хотите узнать больше о самостоятельном присоединении, я опубликовал довольно хороший (хотя и длинный) ответ на вопрос другого пользователя. Проверьте это, если хотите.   -  person John Carrell    schedule 18.09.2015


Ответы (1)


Хорошо, взгляните на запрос ниже и на результаты:

SELECT *
FROM   (SELECT
          cs.cd, cs.dsc, cp.part_cd, cp.qty, cp.dllrs, cp.cu_type
        FROM ck_startup cs
          JOIN ck_price cp ON (cs.prd_type_cd = cp.prd_type_cd))
PIVOT (SUM(dllrs) AS dlllrs FOR (cu_type) IN ('A' AS a, 'AC' AS ac))
ORDER BY cd, qty
;

Выход:

CD       DSC                  PART_CD     QTY   A_DLLLRS  AC_DLLLRS
-------- ----------------- ---------- ------- ---------- ----------
3D       Stuff                      1     100         10            
3D       Stuff                      1     200         20            
3D       Stuff                      1     300         30         30 
DC       Different stuff            1     100         50         50 
DC       Different stuff            1     200        100        100 
DC       Different stuff            1     300                   150 
DC       Different stuff            1     400                   200 
DN2      Similar stuff              1     100         50         50 
DN2      Similar stuff              1     200        100        100 
DN2      Similar stuff              1     300                   150 
DN2      Similar stuff              1     400                   200 

Это не то, что вы ожидали, потому что я не понимаю, почему у вас разные значения в столбце DLLRS_AC, которые находятся в таблице CK_PRICE? Я имею в виду, например, почему у вас 400 в последней строке вашего вывода, а не 200? Почему это значение удвоено (как и другие в столбце DLLRS_AC)?

Если вы используете Oracle 10g, вы можете достичь того же результата, используя DECODE и GROUP BY, посмотрите:

SELECT
        cd,
        dsc,
        part_cd,
        qty,
        SUM(DECODE(cu_type, 'A', dllrs, NULL)) AS dllrs_a,
        SUM(DECODE(cu_type, 'AC', dllrs, NULL)) AS dllrs_ac
FROM (
  SELECT
    cs.cd, cs.dsc, cp.part_cd, cp.qty, cp.dllrs, cp.cu_type
  FROM ck_startup cs
    JOIN ck_price cp ON (cs.prd_type_cd = cp.prd_type_cd)
  )
GROUP BY cd, dsc, part_cd, qty
ORDER BY cd, qty;

Результат тот же.

Если вы хотите узнать больше о вращении, я рекомендую статью Тима Холла: Свернуть и отменить сводку в Oracle Base

person Przemyslaw Kruglej    schedule 04.11.2013
comment
Ой. Я вставил неправильную таблицу CK_PRICE. Я исправлю это. Кроме того, похоже, я работаю с Oracle 10g, поэтому у меня нет pivot возможностей ... - person Logarr; 05.11.2013
comment
@Logarr Я добавил еще одно решение для 10g, используя функцию DECODE, пожалуйста, посмотрите и скажите мне, сработает ли это для вас. - person Przemyslaw Kruglej; 05.11.2013
comment
Блестяще! Я всегда забываю, что вы можете запросить результаты подзапроса. У меня также нет большого опыта работы с функцией DECODE. Большое спасибо! - person Logarr; 05.11.2013