8
I have the following tables:
CREATE TABLE tb_lote
(
id_lote integer NOT NULL DEFAULT nextval('tb_lote_seq'::regclass),
ds_lote character varying(255),
CONSTRAINT pktb_lote PRIMARY KEY (id_lote)
);
CREATE TABLE tb_lote_ticket
(
id_lote_ticket integer NOT NULL DEFAULT nextval('tb_lote_ticket_seq'::regclass),
id_lote integer,
nr_quantidade numeric(12,2) DEFAULT 0,
CONSTRAINT pktb_lote_ticket PRIMARY KEY (id_lote_ticket),
CONSTRAINT fk_tb_lote_ticket_tb_lote FOREIGN KEY (id_lote)
REFERENCES tb_lote (id_lote) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
);
CREATE TABLE tb_processo
(
id_processo integer NOT NULL DEFAULT nextval('tb_processo_seq'::regclass),
id_lote_ticket integer,
id_setor integer,
dt_inicio timestamp without time zone,
CONSTRAINT pktb_processo PRIMARY KEY (id_processo),
CONSTRAINT fk_tb_processo_tb_lote_ticket FOREIGN KEY (id_lote_ticket)
REFERENCES tb_lote_ticket (id_lote_ticket) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_tb_processo_tb_setor FOREIGN KEY (id_setor)
REFERENCES tb_setor (id_setor) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
And the relationship is, Each batch has N ticket and each ticket has 1 process.
- Lote 1..N Ticket
- Ticket 1..1 Processo
I would like to know how to perform an efficient SQL to know the dt_inicio
of each lot in each Setor
and at the same time to "dt_final
".
To dt_final
would be the dt_inicio
of the last process.
Sql Atual
SELECT
Lote.id_lote as "Lote.id_lote",
Setor.ds_setor as "Setor.ds_setor",
Setor.id_setor as "Setor.id_setor",
(
SELECT
ProcesseTmp.dt_inicio
FROM
tb_processo as ProcesseTmp
LEFT JOIN tb_setor as SetorTmp ON SetorTmp.id_setor = ProcesseTmp.id_setor
LEFT JOIN tb_lote_ticket as LoteTicketTmp ON LoteTicketTmp.id_lote_ticket = ProcesseTmp.id_lote_ticket
LEFT JOIN tb_lote as LoteTmp ON LoteTmp.id_lote = LoteOrdemTmp.id_lote
WHERE
LoteTmp.id_lote = Lote.id_lote AND
SetorTmp.id_setor = Setor.id_setor
ORDER BY
ProcesseTmp.dt_inicio
LIMIT 1
) as "Processe.dt_inicio",
(
SELECT
ProcesseTmp.dt_inicio
FROM
tb_processo as ProcesseTmp
LEFT JOIN tb_setor as SetorTmp ON SetorTmp.id_setor = ProcesseTmp.id_setor
LEFT JOIN tb_lote_ticket as LoteTicketTmp ON LoteTicketTmp.id_lote_ticket = ProcesseTmp.id_lote_ticket
LEFT JOIN tb_lote as LoteTmp ON LoteTmp.id_lote = LoteOrdemTmp.id_lote
WHERE
LoteTmp.id_lote = Lote.id_lote AND
SetorTmp.id_setor = Setor.id_setor
ORDER BY
ProcesseTmp.dt_inicio DESC
LIMIT 1
) as "Processe.dt_final",
FROM
tb_mapa_producao as Processe
LEFT JOIN tb_setor as Setor ON Setor.id_setor = Processe.id_setor
LEFT JOIN tb_lote_producao_ordem_ticket as LoteTicket ON LoteTicket.id_lote_ticket = Processe.id_lote_ticket
LEFT JOIN tb_lote_producao as Lote ON Lote.id_lote = Lote.id_lote
WHERE
Processe.dt_inicio BETWEEN '09/09/2015 00:00:00' AND '14/10/2015 23:59:59'
and 1=1
and ( Processe.fl_desativado is false OR Processe.fl_desativado is null )
GROUP BY
Lote.id_lote,
Setor.ds_setor,
Setor.id_setor,
ORDER BY
Lote.id_lote,
Setor.ds_setor,
Setor.id_setor,
Test data
tb_lote
id_lote | ds_lote
1 | teste1
2 | teste2
tb_lote_ticket
id_lote_ticket | id_lote | nr_quantidade
1 | 1 | 10
2 | 1 | 10
3 | 1 | 10
4 | 1 | 10
5 | 1 | 10
6 | 1 | 10
7 | 2 | 10
8 | 2 | 10
9 | 2 | 10
10 | 2 | 10
tb_processo
id_processo | id_lote_ticket | id_setor | dt_inicio
1 | 1 | 3 | 2015-10-01 15:00:00
2 | 2 | 3 | 2015-10-01 15:12:00
3 | 3 | 3 | 2015-10-01 15:24:00
4 | 4 | 4 | 2015-10-01 15:36:00
5 | 5 | 4 | 2015-10-01 15:48:00
6 | 6 | 4 | 2015-10-01 16:00:00
7 | 7 | 6 | 2015-10-01 15:12:00
8 | 8 | 6 | 2015-10-01 15:24:00
9 | 9 | 6 | 2015-10-01 15:36:00
10 | 10 | 6 | 2015-10-01 15:48:00
Expected Result
id_lote | id_setor | dt_inicio | dt_final
1 | 3 | 2015-10-01 15:00:00 | 2015-10-01 15:24:00
1 | 4 | 2015-10-01 15:36:00 | 2015-10-01 16:00:00
2 | 6 | 2015-10-01 15:12:00 | 2015-10-01 15:48:00
That is to say: of each batch, get the start and end date of each sector, and the start date corresponds to the first process of the sector and the end date corresponds to the last process of the sector.
It’s hard to understand the problem. It will help to get good answers from you showing examples of data in all tables and the expected result according to the sample data. Another point is that perhaps a simpler query is more inefficient than your original one in your actual scenario. It will be excessively laborious, boring and possibly ungrateful to consider this aspect in the answers. If you don’t even know how inefficient your query is because efficiency is not a problem - I would take that aspect out of the question.
– Caffé
We can say that of each batch, you want the start date and end date of each sector, and the start date corresponds to the first sector process and the end date corresponds to the last sector process?
– Caffé
@Caffé Exactly this.
– Guilherme Lautert
@Guilhermelautert for us to help you, I recommend putting the creation of tables and data on this site http://sqlfiddle.com/, and pass the url to us. We can help you, because in your example above the table tb_mapa_producao and tb_setor.
– Tiedt Tech