Olá!
CJP escreveu:Mas não entendi o que vc quis dizer com "crie uma CTE". O que seria uma CTE?
Quando vc diz "se todas as suas bases forem MariaDB", quer dizer que eu tenho que usar o Maria DB pra todas?
Common Table Expressions (CTE) ou Expressões Comuns de Tabela é um recurso disponível nos principais sistemas gerenciadores de banco de dados relacionais.
Este recurso não nasceu junto com a especificação de SQL. Foi sendo agregado ao longo do tempo aos diversos SGBDR. No caso do MySQL, foi a partir da versão 8 e no MariaDB, a partir da versão 10.
Desta forma, se você deseja usar CTEs em seu sistema, tem que usar uma versão de SGBDR que suporte esta funcionalidade. Se você for instalar o sistema
em um cliente ou provedor de internet que não tenha disponível a versão correta do SGBD, não será possível usar CTE. Exemplo: você desenvolveu para MySQL 8 com CTE e o cliente tem a versão 5... não vai funcionar.
CJP escreveu:Até entendi a ideia, mas não entendi como fazer isso.
E como faço para executar essa CTE?
Pode me explicar como fazer isso?
No exemplo que postei, as linhas de 1 a 12 criam o CTE e as demais o utilizam.
Veja a criação e uso sem incluir a tua query:
Código: Selecionar todos
WITH recursive Datas AS (
-- "Membro Âncora"
SELECT
Cast( '2021-03-25' As Date) as Data
UNION ALL
-- "Membro Recursivo"
SELECT
Date_Add( Data, INTERVAL 1 DAY)
FROM Datas /* Resultado da última iteração */
WHERE
Data < Cast( '2021-05-03' as Date)
)
SELECT data from datas;
Resultado
# data
1 2021-03-25
2 2021-03-26
3 2021-03-27
4 2021-03-28
5 2021-03-29
...
32 2021-04-25
33 2021-04-26
34 2021-04-27
35 2021-04-28
36 2021-04-29
37 2021-04-30
38 2021-05-01
39 2021-05-02
40 2021-05-03
CJP escreveu:Até tentei executar o teu exemplo no Heidi, mas dá erro no "recursive".
Como visto acima, o CTE está funcionando e gera a faixa de datas corretamente. Então o problema era no resto do código.
Veja exemplo abaixo com a tabela que criei para testes.
Código: Selecionar todos
CREATE TABLE tbAtiv (
id INT(6) NOT NULL AUTO_INCREMENT,
tempousado INT(6),
usuario TEXT(1),
data DATE,
acao VARCHAR(20),
CONSTRAINT tbAtiv_pk PRIMARY KEY (id)
);
---
INSERT INTO tbAtiv (tempousado, usuario, data, acao)
VALUES
( 0, 'G', curdate(), 'Responde' ),
(60, 'G', curdate(), 'Responde' ),
(90, 'G', curdate(), 'Responde' ),
( 0, 'G', Date_Sub( Current_Date(), INTERVAL 1 DAY), 'Atende' ),
(60, 'G', Date_Sub( Current_Date(), INTERVAL 1 DAY), 'Responde' ),
(90, 'G', Date_Sub( Current_Date(), INTERVAL 1 DAY), 'Atende' ),
(11, 'G', Date_Sub( Current_Date(), INTERVAL 2 DAY), 'Responde' ),
(60, 'G', Date_Sub( Current_Date(), INTERVAL 2 DAY), 'Responde' ),
(20, 'G', Date_Sub( Current_Date(), INTERVAL 2 DAY), 'Responde' ),
(60, 'F', Date_Sub( Current_Date(), INTERVAL 3 DAY), 'Responde' ),
(20, 'F', Date_Sub( Current_Date(), INTERVAL 3 DAY), 'Responde' ),
(33, 'G', Date_Sub( Current_Date(), INTERVAL 3 DAY), 'Responde' );
---
SELECT * FROM tbAtiv
--- Resultado
# id tempousado usuario data acao
1 1 0 G 2021-05-07 Responde
2 2 60 G 2021-05-07 Responde
3 3 90 G 2021-05-07 Responde
4 4 0 G 2021-05-06 Atende
5 5 60 G 2021-05-06 Responde
6 6 90 G 2021-05-06 Atende
7 7 11 G 2021-05-05 Responde
8 8 60 G 2021-05-05 Responde
9 9 20 G 2021-05-05 Responde
10 10 60 F 2021-05-04 Responde
11 11 20 F 2021-05-04 Responde
12 12 33 G 2021-05-04 Responde
---
WITH RECURSIVE Datas AS (
-- "Membro Âncora"
SELECT
Cast( '2021-05-01' As Date) as Data
UNION ALL
-- "Membro Recursivo"
SELECT
Date_Add( Data, INTERVAL 1 DAY)
FROM Datas /* Resultado da última iteração */
WHERE
Data < Cast( '2021-05-10' as Date)
)
SELECT d.data Data,
Coalesce( t.tempo, 0) Tempo
FROM Datas d
LEFT JOIN
( SELECT a.DATA,
SUM( a.tempousado) AS tempo
FROM tbAtiv a
WHERE a.usuario='G'
AND a.data >= '2021-05-01'
AND a.data < '2021-05-10'
AND a.acao='Responde'
GROUP BY a.DATA
HAVING tempo < 90 ) t
ON d.data = t.data
ORDER BY data;
--- Resultado
# Data Tempo
1 2021-05-01 0
2 2021-05-02 0
3 2021-05-03 0
4 2021-05-04 33
5 2021-05-05 0
6 2021-05-06 60
7 2021-05-07 0
8 2021-05-08 0
9 2021-05-09 0
10 2021-05-10 0
---
JoséQuintas escreveu:Convém lembrar que tudo é criado em memória, então é bom usar pra informações reduzidas, não pra SELECT *
Não vejo restrições no uso, independentemente do volume de informações. Creio que, conforme o volume, ele use disco também, além da memória.
Pode ser usado tanto para SELECT como para INSERT, UPDATE, DELETE e CREATE TABLE.
Pode ter vários membros recursivos ou não, separados por vírgula. Quando pelo menos um membro é recursivo, é obrigatório usar a palavra
RECURSIVE.