Estou tentando escrever um script que combine resultados de pesquisas específicas com base nas demografias usadas na pesquisa. Eu consegui escrever um script que adiciona demógrafos juntos para criar um novo demógrafo, por exemplo, M18+ e F18+ = A18+, que funciona perfeitamente, no entanto, ao tentar criar um script que criará um intervalo demográfico, por exemplo, A18-24, estou encontrando alguns problemas não pode resolver.
Meu primeiro script que adiciona dois demógrafos é o seguinte:
create table #SurveyTemp
(
Com nchar(6),
Survey nvarchar(50),
Demo nchar(50),
Wk int,
Time int,
Aud decimal(18,8)
);
insert into #SurveyTemp (Com, Survey, Demo, Wk, Time, Aud)
select Com, Survey, 'A18+', Wk, Time, sum(Aud)
from table_survey
where survey = 'LO2017'
and demograph like 'F18+'
or surveyid = 'LO2017'
and demograph like 'M18+'
group by Com, survey, Wk, Time:
insert into table_survey
select temp.Com, temp.Survey, temp.Demo, temp.Wk, temp.Time, temp.Aud
from #SurveyTemp temp
drop table #SurveyTemp
Este script funciona bem. Ele adiciona dois demógrafos e insere novas linhas de dados, criando uma soma do público para cada Com, Survey, Wk e, em seguida, Time. Veja o conjunto de dados de amostra abaixo onde a adição de M18+ e F18+ criou um novo registro chamado A18+
Deixe-me começar com um conjunto de dados de exemplo: (Isenção de responsabilidade: o banco de dados ativo tem MUITAS linhas para cada demógrafo)
com | surveyid | demo | wk | time | audience
-------------------------
1 | LO2017 | A18+ | 1 | 300 | 4.7
1 | LO2017 | F18+ | 1 | 300 | 1.9
1 | LO2017 | M18+ | 1 | 300 | 2.8
1 | LO2017 | A25+ | 1 | 300 | 2.3
1 | LO2017 | A18+ | 2 | 100 | 3.7
1 | LO2017 | F18+ | 2 | 100 | 1.9
1 | LO2017 | M18+ | 2 | 100 | 2.8
1 | LO2017 | A25+ | 2 | 100 | 4.3
O que eu preciso escrever agora é um script que cria um intervalo. Observe como na tabela acima há um A18+ e um A25+. Por favor, tenha em mente que na minha tabela ao vivo haverá várias linhas para todos os demógrafos.
Neste exemplo, usarei a tabela acima. Então, preciso criar um script semelhante que some o público de dois demógrafos e depois subtraia um do outro para criar um intervalo. Por exemplo, subtraia os dados A25+ de A18+ para criar um intervalo chamado A1824. Espero que faça sentido.
No script abaixo, estou tentando criar um intervalo chamado 'A1824', mas estou recebendo um erro "subconsulta retornou mais de 1 linha" OU está inserindo os dados errados na tabela temporária onde a soma em AudOne e AudTwo é o MESMO para cada semana e hora.
create table #SurveyTemp
(
Com nchar(6),
Survey nvarchar(50),
Demo nchar(50),
Wk int,
Time int,
Aud decimal(18,8),
AudOne decimal(18,8),
AudTwo decimal(18,8)
);
insert into #SurveyTemp (Com, Survey, Demo, Wk, TimeBlock, Aud, AudOne, AudTwo)
(select Com, Survey, 'A1824', Wk, Time, 0.0,
(select sum(aud) from table_survey where demo = 'A18+'),
(select sum(aud) from table_survey where demo = 'A25+')
from table_survey
where surveyid = 'LO2017'
group by Com, survey, Wk, Time,
)
update #SurveyTemp
set Aud = AudOne - AudTwo;
insert into table_survey
select temp.Com, temp.survey, temp.demo, temp.Wk, temp.Time, temp.aud
from #SurveyTemp temp
drop table #SurveyTemp
É esse segundo script que preciso começar a trabalhar e passei horas tentando resolver sem muita sorte. Por favor, deixe-me saber se eu posso fornecer mais informações para ajudá-lo a me ajudar!
Edit: Meus resultados esperados seriam algo como o seguinte:
com | surveyid | demo | wk | time | audience
-------------------------
1 | LO2017 | A1824 | 1 | 300 | 2.4
Mas haveria várias linhas onde existem várias entradas 'wk' e 'time'. Por exemplo:
com | surveyid | demo | wk | time | audience
-------------------------
1 | LO2017 | A1824 | 1 | 100 | 2.4
1 | LO2017 | A1824 | 1 | 200 | 3.7
1 | LO2017 | A1824 | 2 | 100 | 2.1
1 | LO2017 | A1824 | 2 | 200 | 6.2
Vou começar depois que você gerar a tabela #SurveyTemp.
Não tenho certeza se entendi seu resultado esperado, dê uma olhada na sua tabela ordenada por demo:
Existem 2 registros para cada demonstração. Se você deseja adicionar um novo registro como resultado de alguma operação entre esses dois registros, você deve decidir se deseja agrupar por semana e hora (que acho que é a maneira correta) ou não.
No seu comando de inserção:
Você está agrupando por
Com, Survey, Wk, Time
, mas está calculando o público geral de todos os registros de demonstração (sem considerar a semana e o tempo):IMHO, pelo menos,
wk
deve ser adicionado aos novos registros, e você deve decidir o que fazer com o tempo.Minha solução proposta: GROUP BY WK AND TIME
NOTA: Eu adicionei
wk
etime
para calcularsum(audience)
para cada demonstração.Como você pode ver, o primeiro registro corresponde ao seu resultado esperado.
Sem grupo por semana e hora
Este é o resultado:
NOTA: Você não precisa INSERT & UPDATE, isso pode ser feito em uma única operação INSERT.
Confira: dbfiddle aqui