Как создать представление из существующих записей таблицы, а также добавить новые записи, которые не существуют - PullRequest
0 голосов
/ 16 января 2019

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

SELECT
    s_date,
    part_no,
    issue_group,
    s_level,
    qty_filled
FROM
    current_view
WHERE
    part_no = 'xxxxx'
    AND s_date IN (
        '201802',
        '201803'
    )
ORDER BY
    s_date,
    part_no,
    issue_group,
    DECODE(s_level, '80', 1, '100', 2, 'Late', 3)

Который производит ниже:

enter image description here

Я знаю, как создать представление с этими данными, это самая простая часть. Но мне нужна строка для каждой комбинации issue_group and s_level, и, если это созданная строка, поставить 0 в качестве qty_filled.

Каждое комбо part_no / s_date должно иметь 6 строк, которые идут вместе с ним

 - issue_group = '1' / s_level = '80'
 - issue_group = '1' / s_level = '100'
 - issue_group = '1' / s_level = 'Late'
 - issue_group = '2/3 ' / s_level = '80'
 - issue_group = '2/3 ' / s_level = '100'
 - issue_group = '2/3 ' / s_level = 'Late'

Таким образом, если одна из вышеперечисленных комбинаций уже существует для текущего s_date/part_no, то она, очевидно, берет информацию qty_filled из текущего представления. Если нет, то создается новая строка и qty_filled = 0. Поэтому я пытаюсь заставить его выглядеть так:

enter image description here

Я только показал 1 часть, с парой свиданий, просто чтобы понять суть. В таблице содержится 10 000+ частей, и для каждой из 6 комбинаций Issue_group / s_level никогда не будет более 1 комбо части / даты.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Идея состоит в том, чтобы сгенерировать строки, используя CROSS JOIN, а затем ввести дополнительную информацию с помощью LEFT JOIN. В синтаксисе Oracle это выглядит так:

WITH v as (
      SELECT v.*
      FROM current_view v
      WHERE part_no = 'xxxxx' AND
            s_date IN ('201802', '201803')
    )
SELECT d.s_date, ig.part_no, ig.issue_group, l.s_level,
       COALESCE(v.qty_filled, 0) as qty_filled
FROM (SELECT DISTINCT s_date FROM v) d CROSS JOIN
     (SELECT DISTINCT part_no, ISSUE_GROUP FROM v) ig CROSS JOIN
     (SELECT '80' as s_level FROM DUAL UNION ALL
      SELECT '100' FROM DUAL UNION ALL
      SELECT 'LATE' FROM DUAL
     ) l LEFT JOIN
     v
     ON v.s_date = d.s_date AND v.part_no = ig.part_no AND
        v.issue_group = ig.issue_group AND v.s_level = l.s_level
ORDER BY s_date, part_no, issue_group,
         (CASE s_level WHEN  '80' THEN 1 WHEN '100' THEN 2 WHEN 'Late' THEN 3 END)
0 голосов
/ 16 января 2019

Одним из решений может быть генерирование декартового произведения всех ожидаемых строк с использованием декартового произведения между (фиксированным) списком значений, а затем LEFT JOIN с помощью current_view.

Следующий запрос гарантирует, что вы получите запись для каждого данного s_date/part_no/issue_group/s_level кортежа. Если в current_view не найдено ни одной записи, запрос отобразит количество 0.

SELECT
    sd.s_date,
    pn.part_no,
    ig.issue_group,
    sl.s_level,
    COALESCE(cv.qty_filled, 0) qty_filled
FROM
    (SELECT '201802' AS s_date UNION SELECT '201803') AS sd
    CROSS JOIN (SELECT 'xxxxx' AS part_no) AS pn
    CROSS JOIN (SELECT '1' AS issue_group UNION SELECT '2') AS ig
    CROSS JOIN (SELECT '80' AS s_level UNION SELECT '100' UNION SELECT 'Late') AS sl
    LEFT JOIN current_view cv 
        ON  cv.s_date      = sd.s_date
        AND cv.part_no     = pn.part_no
        AND cv.issue_group = ig.issue_group
        AND cv.s_level     = ig.s_level
ORDER BY
    sd.s_date,
    pn.part_no,
    ig.issue_group,
    DECODE(sl.s_level, '80', 1, '100', 2, 'Late', 3)

NB. Вы не отметили свою СУБД. Это должно работать на большинстве из них, за исключением Oracle, где вам нужно добавить FROM DUAL к каждому выбору в запросах, которые перечисляют допустимые значения, например:

(SELECT '201802' AS s_date FROM DUAL UNION SELECT '201803' FROM DUAL) AS sd
...