Дело в том, что вы можете преобразовать цикл for в цикл while / repeat. Обратите внимание, как вы проверяете i & lt; длина каждый раз. Если вы его скрываете,
do {
} while (array[i++] != elementToSearch);
Тогда вам не нужно делать дополнительную проверку. (в этом случае array.length теперь больше)
Одним из решений может быть создание декартового произведения всех ожидаемых строк с использованием декартового произведения между (фиксированным) списком значений, а затем 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)
Примечание: вы не пометили свою СУБД. Это должно работать на большинстве из них, за исключением Oracle, где вам нужно добавить FROM DUAL
к каждому выбору в запросах, которые перечисляют допустимые значения, например:
(SELECT '201802' AS s_date FROM DUAL UNION SELECT '201803' FROM DUAL) AS sd
Идея состоит в том, чтобы сгенерировать строки, используя 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)