У меня возникла проблема с поиском правильного SQL-запроса для моей программы.
В основном мне приходится использовать две таблицы: Картон и Производство. У Cardboard есть Cardboard_Number, где последние 10 цифр обозначают номер накладной. Мне нужно найти запрос, который выбирает все продукты на основе входных данных PRODUCTION_NUMBER и POSNR, найти все номера накладных в производстве и, наконец, найти все продукты, в которых также использовался любой из номеров накладных. При поиске Произведений по номерам использованных накладных мне необходимо знать каждое Производство, в котором оно использовалось, независимо от того, когда и в какой строке оно использовалось.
У меня уже есть два запроса, которые почти выполняют мою работу, но я не уверен, как изменить и объединить их в один эффективный запрос, чтобы он соответствовал моим требованиям. (Запросы также включены в скрипт)
См. эту dbfiddle для примера данных, ожидаемого результата и более подробного описания.
Чтобы объяснить используемое «смещение»: в основном при поиске номера накладной я хочу получить все картоны, которые содержат этот номер + все картоны, которые были отсканированы до и после того, как каждый из них был найден на конкретной производственной линии. Более подробное объяснение смотрите в этой теме StackOverflow.
Редактировать:
Чтобы получить связь между производством и номером накладной, мне, по сути, нужно найти все картоны, отсканированные между Production_StartDT и Production_EndDT (я получаю начало и конец простым выбором, поскольку в качестве входных данных у меня есть PRODUCTION_NUMBER и POSNR). Как уже было сказано, последние 10 цифр Cardboard_Number обозначают номер накладной. Тогда мне пришлось бы найти все остальные Произведения, независимо от того, на какой производственной линии и независимо от начала и конца, в которых также использовался любой из номеров накладных.
Образец данных:
| PRODUCTION_NUMBER | POSNR | START_DT | END_DT | PRODUCTION_LINE |
| -----------------:|------:|:-------------------|:-------------------|----------------:|
| 12344 | 1 | 28-FEB-24 14.02.35 | 29-FEB-24 18.02.35 | 2 |
| 12345 | 1 | 29-FEB-24 18.22.40 | 07-MAR-24 18.22.40 | 1 |
| 12345 | 2 | 05-MAR-24 13.02.35 | 12-MAR-24 13.02.35 | 2 |
| 12345 | 2 | 14-MAR-24 14.02.35 | 16-MAR-24 13.02.35 | 2 |
| CARDBOARD_NUMBER | DATE_TIME | PRODUCTIONLINE_NUMBER |
| :----------------|:-------------------|----------------------:|
| WDL-005943998-1 | 05-AUG-14 10.03.32 | 1 |
| spL1ml82N4o | 29-FEB-24 17.13.54 | 1 |
| WDL-005943998-1 | 01-MAR-24 09.44.42 | 1 |
| WDL-005943998-1 | 01-MAR-24 10.34.57 | 1 |
| 950024027237 | 01-MAR-24 10.44.57 | 1 |
| 950024027237 | 01-MAR-24 10.52.57 | 1 |
| WDL-005943998-1 | 01-MAR-24 13.58.43 | 2 |
| WDL-005943998-1 | 01-MAR-24 13.58.46 | 2 |
| spL1ml82N4o | 01-MAR-24 14.09.43 | 2 |
| WDL-005943998-1 | 12-MAR-24 11.48.36 | 2 |
With Cardboard_offset(cardboard_number, date_time, productionline_number) as (
select cardboard_number, date_time, productionline_number
from (
SELECT cardboard_number, date_time, productionline_number,
sum(case when Cardboard_Number like CONCAT('%', '05943998-1') then 1 else 0 end) over (
partition by ProductionLine_Number
order by date_time
rows BETWEEN 1 preceding AND 1 following
) matches
from cardboard
) table1_with_matches
where matches > 0
)
SELECT distinct p.production_number,
p.posnr,
p.production_line,
p.start_dt,
p.end_dt
FROM production p
INNER JOIN cardboard_offset c
ON p.production_line = c.productionline_number
AND c.date_time BETWEEN p.start_dt AND p.end_dt
| PRODUCTION_NUMBER | POSNR | PRODUCTION_LINE | START_DT | END_DT |
| -----------------:|------:|----------------:|:-------------------|:-------------------|
| 12345 | 1 | 1 | 29-FEB-24 18.22.40 | 07-MAR-24 18.22.40 |
| 12345 | 2 | 2 | 05-MAR-24 13.02.35 | 12-MAR-24 13.02.35 |
select d.cardboard_number, d.date_time, d.productionline_number
from production a
join lateral
(
select cardboard_number, date_time, productionline_number
from (
SELECT cardboard_number, date_time, productionline_number,
sum(case when date_time between a.start_dt and a.end_dt then 1 else 0 end) over (
partition by ProductionLine_Number
order by date_time
rows BETWEEN 1 preceding AND 1 following
) matches
from cardboard
) table1_with_matches
where matches > 0
) d on a.production_line = d.productionline_number
where a.production_number = 12345 and a.posnr = 1
| CARDBOARD_NUMBER | DATE_TIME | PRODUCTIONLINE_NUMBER |
| :----------------|:-------------------|----------------------:|
| spL1ml82N4o | 29-FEB-24 17.13.54 | 1 |
| WDL-005943998-1 | 01-MAR-24 09.44.42 | 1 |
| WDL-005943998-1 | 01-MAR-24 10.34.57 | 1 |
| 950024027237 | 01-MAR-24 10.44.57 | 1 |
| 950024027237 | 01-MAR-24 10.52.57 | 1 |
12344 - 1 (because delivery note number 'pL1ml82N4o' was used in this production)
12345 - 1 (because delivery note numer '05943998-1' was used in this production)
12345 - 2 (because delivery note numer '05943998-1' was used in this production)
@NickW Я обновил свой вопрос и добавил дополнительную информацию, надеюсь, она окажется для вас полезной.
Я нашел решение:
SELECT distinct p.production_number,
p.posnr,
p.production_line,
p.start_dt,
p.end_dt
from Production production
join
(
select d.cardboard_number, d.date_time, d.productionline_number
from production a
join lateral
(
select distinct SUBSTR(d.cardboard_number, -10), date_time
from (
SELECT cardboard_number, date_time, productionline_number,
sum(case when date_time between a.start_dt and a.end_dt then 1 else 0 end) over (
partition by ProductionLine_Number
order by date_time
rows BETWEEN 1 preceding AND 1 following
) matches
from cardboard
) table1_with_matches
where matches > 0
) d on a.production_line = d.productionline_number
where a.production_number = 12345 and a.posnr = 1
) ca on ca.date_time between production.start_dt and production.end_dt;
Привет! Все вопросы на этом форуме должны быть самодостаточными, поэтому, пожалуйста, не ссылайтесь на внешние сайты, которые содержат часть информации, необходимой для помощи вам (объяснение смещений); добавьте эту информацию в свой вопрос. Кроме того, в своем вопросе вы сказали «найти все номера накладных в производстве» - однако в таблице «Производство», похоже, нет ничего, что соответствовало бы номеру накладной, не могли бы вы объяснить это более подробно?