Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde.
Tenho o seguinte tabela.
Campos
Assunto | evento
Valores
Teste1 | send
Teste1 | open
Teste2 | send
Teste3 | send
Teste1 | click
Teste2 | open
Repare que somente o Teste3 não consta o evento como send ou click.
Não estou conseguindo montar uma SELECT que liste somente os registros que contém send mas que não contém outro evento.
Ainda não consegui. Vou fazer algumas tentativas.
Select *
from valores v1
Where v1.assunto = 'open' /tras apenas os "open"/
And not exists (/verifica se existem para o assunto os eventos da lista/
select null
From valores v2 /*compara a mesma tabela da sql acima*/
Where v2.assunto = v1.assunto
And v2.evento in ('send','click'))Bom dia. Teste aqui não trouxe resultados. Vou observar o seu código.
Opaaa...deu certo hein. Eu estava fazendo uma coisa errada. Sua string deu certo. Valeu pela ajuda. Vou analisar o que foi feito, afim de aprender.
Obrigado.
Vide edição.
Motta agora complicou um pouco.
Veja só. Na linha 3 eu recebo um post externo qu não que manda o assunto e nem o email quando o evento é "opened".
Preciso no código que você passou a identificar emails que não foram abertos checando se não consta uma linha "opened", sendo que o campo único e identificador é o código.
Antes você igualava com o assunto, eu tenho igualar com o código mas não rolou.
Meu código:
SELECT COUNT(id_log) as total
FROM log l1
WHERE l1.evento = 'delivered'
AND (sender = 'email2@email.com' OR
msg_id IN (SELECT msg_id
FROM log
WHERE sender = 'email2@email.com.br'))
AND NOT EXISTS (SELECT null
FROM log l2
WHERE l2.msg_id = l1.msg_id
AND (sender = 'email2@email.com' OR
msg_id IN (SELECT msg_id
FROM log
WHERE sender = 'email2@email.com.br'))01@PC | Teste não 2 | email1@email.com | email2@email.com | accepted
01@PC | Teste não 2 | email1@email.com | email2@email.com | delivered
01@PC | '' | email1@email.com | '' | opened
02@PC | Teste 3 | email1@email.com | email2@email.com | accepted
02@PC | Teste 3 | email1@email.com | email2@email.com | delivered
Desculpe , não entendi.
No seu código tem essa parte:
v2.assunto = v1.assunto
O problema é que a minha tabela quando o campo chamado evento não é sempre que tem valor.
O campo que tem valor sempre é o msg_id, ai no meu código eu coloquei isso.
l2.msg_id = l1.msg_id
Posso gerar um insert com os valores da tabela para você entender melhor? ai se você tiver uma base de testes daria um insert com os meus valores para entender melhor.
Mas vou tentar explicar melhor.
Repare a linha abaixo
01@PC | '' | email1@email.com | '' | opened
Não tem valor no campo assunto que é o segundo campo e não tem valor no quarto campo.
No seu código está usando v2.assunto = v1.assunto O fato de eu não ter valor creio que vai dar erro.
A estrutura da sua tabela é esta mesmo ou tem algum outro campo?
Só tem esses campos:
codigo | assunto | email | sender | evento
01@PC | Teste não 2 | email1@email.com | email2@email.com | accepted
01@PC | Teste não 2 | email1@email.com | email2@email.com | delivered
01@PC | '' | email1@email.com | '' | opened
02@PC | Teste 3 | email1@email.com | email2@email.com | accepted
02@PC | Teste 3 | email1@email.com | email2@email.com | delivered
Veja que na tabela acima a linha 3 tem um evento chamado "opened", portando eu digo que esse email foi aberto.
Não pode exibir essa linha.
O quarta e quinta linha é um email que não foi aberto, então eu tenho um total de 1 email não aberto. Juntamente esse total que tenho que ter na minha consulta.
Vamos lá.
Se vc tem um email com duas condiçoes de evento, veja se o exemplo abaixo lhe serve:
declare @email table (id int identity (1,1)
, codigo varchar(100)
, assunto varchar(max)
, email varchar(100)
, sender varchar(100)
, evento varchar(100)
)
insert into @email select '01@PC', 'Teste não 2', 'email1@email.com ', 'email2@email.com','accepted'
insert into @email select '01@PC','Teste não 2','email1@email.com','email2@email.com','delivered'
insert into @email select '01@PC','','email1@email.com','''','opened'
insert into @email select '02@PC','Teste 3','email1@email.com','email2@email.com','accepted'
insert into @email select '02@PC','Teste 3','email1@email.com','email2@email.com','delivered'
select b.* from (
SELECT COUNT(*) as qtde
, assunto
from @email
group by assunto
having COUNT(*) = 2
) a inner join @email b on a.assunto = b.assunto
order by b.idOlá.
Ainda não é isso. Na tabela abaixo preciso fazer um select comparando ela mesma.
Exemplo: listo tudo que tenha "delivered" mas que não tenha "opened". O resultado tem que ser um Count. No caso abaixo o COunt deveria dar 1, pois o email com assunto "Teste 3" não tem nenhuma linha com "opened"
01@PC | Teste não 2 | email1@email.com | email2@email.com | accepted
01@PC | Teste não 2 | email1@email.com | email2@email.com | delivered
01@PC | '' | email1@email.com | '' | opened
02@PC | Teste 3 | email1@email.com | email2@email.com | accepted
02@PC | Teste 3 | email1@email.com | email2@email.com | delivered
O caminho é o que o Motta me ajudou, falta alguma coisa que não está dando certo.
SELECT COUNT(id_log) as total
FROM log l1
WHERE l1.evento = 'delivered'
AND (sender = 'email2@email.com' OR
msg_id IN (SELECT msg_id
FROM log
WHERE sender = 'email2@email.com.br'))
AND NOT EXISTS (SELECT null
FROM log l2
WHERE l2.msg_id = l1.msg_id
AND (sender = 'email2@email.com' OR
msg_id IN (SELECT msg_id
FROM log
WHERE sender = 'email2@email.com.br'))
AND l1.evento <> ('delivered'))
Motta ou A.Jr podem dar uma ajuda.
não entendi o motivo do "festival de OR" .... :)
dica : faça como o Jake , vá por partes
1 ) monte a query básica do
tudo que tenha "delivered"
2 ) com base nela e usando um NOT EXISTS faça o
mas que não tenha "opened"
a tabela do subselect pode ou não ser a mesma da sql principal
um sql com join pode ser uma "tabela virtual" e esta se retetir no subselect.
https://msdn.microsoft.com/pt-br/library/ms188336.aspx
Use o o NOT EXISTS , é uma solução.