Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

brunoguitarman

Sql Complicado - Dor de cabeça!

Recommended Posts

Galera, preciso fazer um sql que está me dando dor de cabeça. Talvez alguém aí possa me ajudar.

Tenho um conjunto de dados como o que segue

id	Ano	Mes	programa	acao	etapa	tipoAcao	indicador	expectativa	periodicidade	cargo	setor	orgao	data	meta	medido	desempenho	cor	acaoIndicador	analiseIndicador	verificado	dataInicial	dataFinal	status
566690	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-04-30 00:00:00.000	1	1	100	VD			Sim	2014-01-01 00:00:00.000	2014-04-30 00:00:00.000	A
566689	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-08-31 00:00:00.000	2	0	0	VD			Sim	2014-05-01 00:00:00.000	2014-08-31 00:00:00.000	F
566688	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-12-31 00:00:00.000	3	0	0	VD			Sim	2014-09-01 00:00:00.000	2014-12-31 00:00:00.000	F
564361	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Intervenções para Melhoria do Atendimento das Políticas Sociais	Aumentar	semestral	Lider da Ação	Gabinete	SMGL	2014-06-30 00:00:00.000	1	1	100	VD			Sim	2014-01-01 00:00:00.000	2014-06-30 00:00:00.000	A
564360	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Intervenções para Melhoria do Atendimento das Políticas Sociais	Aumentar	semestral	Lider da Ação	Gabinete	SMGL	2014-12-31 00:00:00.000	2	0	0	VD			Sim	2014-07-01 00:00:00.000	2014-12-31 00:00:00.000	F
564172	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Casa dos Conselhos	Aumentar	anual	Líder da Ação	Conselhos Municipais	SMGL	2014-12-31 00:00:00.000	37	0	0	CZ			Sim	2014-01-01 00:00:00.000	2014-12-31 00:00:00.000	F
564171	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Casa dos Conselhos	Aumentar	anual	Líder da Ação	Conselhos Municipais	SMGL	2015-12-31 00:00:00.000	79	0	0	CZ			Sim	2015-01-01 00:00:00.000	2015-12-31 00:00:00.000	F
564170	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Casa dos Conselhos	Aumentar	anual	Líder da Ação	Conselhos Municipais	SMGL	2016-12-31 00:00:00.000	90	0	0	CZ			Sim	2016-01-01 00:00:00.000	2016-12-31 00:00:00.000	F
564169	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Casa dos Conselhos	Aumentar	anual	Líder da Ação	Conselhos Municipais	SMGL	2017-12-31 00:00:00.000	100	0	0	CZ			Sim	2017-01-01 00:00:00.000	2017-12-31 00:00:00.000	F
564574	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Conselhos Municipais com Página WEB	Aumentar	anual	Líder da Ação	Gestão de Democracia Participativa	SMGL	2013-12-31 00:00:00.000	0	6	0	CZ			Sim	2013-01-01 00:00:00.000	2013-12-31 00:00:00.000	A
564573	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Conselhos Municipais com Página WEB	Aumentar	anual	Líder da Ação	Gestão de Democracia Participativa	SMGL	2014-12-31 00:00:00.000	13	0	0	CZ			Sim	2014-01-01 00:00:00.000	2014-12-31 00:00:00.000	F
564572	2014	6	CIDADE DA PARTICIPAÇÃO	ARTICULAÇÃO DOS CONSELHOS MUNICIPAIS	NULL	Correntes	Conselhos Municipais com Página WEB	Aumentar	anual	Líder da Ação	Gestão de Democracia Participativa	SMGL	2015-12-31 00:00:00.000	26	0	0	CZ			Sim	2015-01-01 00:00:00.000	2015-12-31 00:00:00.000	F

O que acontece?

Todo mês uma planilha é importada no sistema contendo dados brutos como esses.
Cada vez que a planilha é importada é guardado o ano e o mês de importação (como podem ver, a coluna ano contém 2014 e a coluna mês contém 6).
Pois bem, então preciso fazer um agrupamento no fim por ano e mês.

No geral o que preciso fazer é para cada entrada de dados (essa planilha importada mensalmente) descobrir quantos indicadores tenho dentro de cada programa. Um programa é composto por ações e as ações possuem indicadores. Até aí tudo bem: faria o group by pelo ano, mes, data, programa, ação, indicador e depois faria um count dos indicadores.

Agora a coisa complica um pouquinho. Você me pergunta por quê? Eu te respondo por quê! heheeh
Sempre devemos considerar apenas o tipoAcao 'Correntes' e verificado = 'Sim'.

Tá, mas, Brunoooo, o que tem de complicado nisso? Nada! É só colocar um where e pronto!

OK, até aqui tudo bem. O problema mesmo começa agora:

Temos a coluna 'status' no qual temos o valor 'A' para a medição atual e o valor 'F' para as metas do futuro.

Temos vários tipos de medição, que podem ser verificados na coluna 'periodicidade'. Eles podem ser 'mensal', 'bimestral', 'trimestral', 'quadrimestral', 'semestral', ou 'anual'.

Então primeiro precisamos selecionar um subconjunto no qual o status é 'A', a coluna data deve ser verificada de acordo com a periodicidade. Por exemplo, se a periodicidade for mensal, o valor da coluna deve ser algum dia de maio, se for quadrimestral, deve ser num dos últimos 4 meses, se for semestral deve ser num dos últimos 6 meses.
Após fazer essa verificação, deve-se verificar se há valor na coluna 'medido'.
Se esses requisitos forem preenchidos, ok, o indicador ainda pode ser contado, se não, está fora.

Agora, devemos verificar se o indicador possui meta para o restante do tempo.
As metas são verificadas quando a coluna status tem o valor 'F' e a coluna meta está preenchida, ou então, se ela não estiver preenchida, as colunas acaoIndicador e analiseIndicador devem estar preenchidas.
Para um indicador com periodicidade mensal, no mês de junho, deve possuir metas para os próximos meses do ano (Jul, Ago, Set, Out, Nov, Dez).
Se passar por isso tudo, ele pode entrar na conta da quantidade de indicadores que temos. Caso contrário, está fora.

Exemplo:

d	Ano	Mes	programa	acao	etapa	tipoAcao	indicador	expectativa	periodicidade	cargo	setor	orgao	data	meta	medido	desempenho	cor	acaoIndicador	analiseIndicador	verificado	dataInicial	dataFinal	status
566690	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-04-30 00:00:00.000	1	1	100	VD			Sim	2014-01-01 00:00:00.000	2014-04-30 00:00:00.000	A
566689	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-08-31 00:00:00.000	2	0	0	VD			Sim	2014-05-01 00:00:00.000	2014-08-31 00:00:00.000	F
566688	2014	6	CIDADE DA PARTICIPAÇÃO	AÇÕES DE POLÍTICAS SOCIAIS	NULL	Correntes	Ações de Empoderamento Local da Comunidade Santo André	Aumentar	quadrimestral	Líder da Ação	Governança Rede de Sustentabilidade e Cidadania	SMGL	2014-12-31 00:00:00.000	3	0	0	VD			Sim	2014-09-01 00:00:00.000	2014-12-31 00:00:00.000	F

Essas 3 linhas estão agrupadas pelo ano 2014, mês 6, programa CIDADE DA PARTICIPAÇÃO, ação AÇÕES DE POLÍTICAS SOCIAIS, indicador Ações de Empoderamento Local da Comunidade Santo André.

Ele é um indicador quadrimestral. É verificado e seu tipo de ação é corrente. OK, ele entra nesses requisitos.
A medição atual está em Abril. Como é quadrimestral, está valendo.
Ele possui duas linhas com metas no futuro (Agosto e Dezembro). Então esse indicador entra para aquela contagem final. Mas caso não tivesse dezembro, por exemplo, já não entraria.


Então, deu pra entender meu problema? Alguém pode me dar uma luz de como fazer todas essas verificações?

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vc fez as perguntas e vc mesmo as respondeu....

 

A cada verificacao/passo você ter que ter estes dados em uma tabela temporaria, por exemplo, mas antes de mais nada, estes caras sao para relatorios? saida de sistema? como que eh feita a importacao? por SSIS? Pode fazer o tratamento jah na importacao dos dados.

Qual a versao do SQL em questao?

 

[]´s

Compartilhar este post


Link para o post
Compartilhar em outros sites

O SQL é o 2012.
É um sistema em php. A planilha é lida utilizando o phpexcel e guardada numa tabela que é idêntica à planilha, diferindo apenas que ela tem um ID como PK e as colunas ano e mês para controle de entrada de dados.

Após isso, o sistema possui uma rotina em que utiliza esta e diversas outras tabelas para calcular os valores de outras variáveis. Essas variáveis, cada uma possui uma view que é feito um select para guardar os dados em uma tabela de histórico desses dados (sim, o banco de dados é meio tosco, mas não posso muda-lo). Posteriormente, para exibir os dados na tela, o sistema busca os dados somente dessa tabela histórico.

O grande problema é que não estou conseguindo montar a lógica dos selects e subqueries.
Aquela parte de buscar uma linha atual para depois verificar as futuras e somente contar quando houver todas as metas futuras necessárias está dando um nó na minha cabeça.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vou montar um ambiente de teste e importar estes dados que você tem ai e tentar seguir o que falou....

Nada como ter um dia de folga e estudar um pouco B)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pronto.

SQL2012 e planilha importada.

Vamos tentar segmentar as suas duvidas ok?!

 

 


Sempre devemos considerar apenas o tipoAcao 'Correntes' e verificado = 'Sim'.

Affff

Digitei um texto imenso e se perdeu ¬¬

Compartilhar este post


Link para o post
Compartilhar em outros sites

@brunoguitarman , seria legal você elencar suas dúvidas.

 

Pelo que entendi uma das dúvidas e relacionar o período do indicador ao intervalo de data,

tipo quadrimestre (jfm,amj,jas,ond) semastre (jfmamj,jasond)

Compartilhar este post


Link para o post
Compartilhar em outros sites

@brunoguitarman , seria legal você elencar suas dúvidas.

 

Pelo que entendi uma das dúvidas e relacionar o período do indicador ao intervalo de data,

tipo quadrimestre (jfm,amj,jas,ond) semastre (jfmamj,jasond)

No momento minha maior dúvida é:

Uma vez que eu tenho retornadas todas as linhas com as medições atuais, como faço para verificar para cada uma delas quais as suas metas e se ela possui todas as metas necessárias?

 

O meu grande problema é que estou viciado no pensamento de uma linguagem de programação.

Por exemplo, pegaria todas as linhas de medições atuais, percorreria todas elas buscando as metas.

Verificaria se possui todas as metas.

Finalmente incrementaria um contador.

 

Isso cheio de foreachs, ifs e qualquer outra coisa que o valha. Eu não estou conseguindo pensar como fazer isso com o sql.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Deu até raiva ¬¬

escrevi tudo bonitinho e nem salvei ¬¬

vou tentar recobrar a lógica e a dúvida que eu tinha ¬¬

Compartilhar este post


Link para o post
Compartilhar em outros sites

Deu até raiva ¬¬

escrevi tudo bonitinho e nem salvei ¬¬

vou tentar recobrar a lógica e a dúvida que eu tinha ¬¬

 

No Oracle tem uam tabela/view (v$sql) que guarda os SQLs executados, às vezes dá para recuperar um SQL "perdido" por ela ?

Sql Server tem algo parecido ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Acho que o A.Jr se irritou tanto que desistiu :P.

Alguma ideia, povo?

Desisti não... só que sexta ocorreu alguns "causos" hehehe

Agora preciso eh retornar o raciocínio :devil:

 

 

No Oracle tem uam tabela/view (v$sql) que guarda os SQLs executados, às vezes dá para recuperar um SQL "perdido" por ela ?

Sql Server tem algo parecido ?

Isso foi no fórum... ¬¬ tentei fazer uma tratativa de duvidas com algumas observacoes com o "quote" e sumiu tudo ¬¬

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vamos voltar ao post? :p

E vamos a primeira duvida:

 

 


Temos a coluna 'status' no qual temos o valor 'A' para a medição atual e o valor 'F' para as metas do futuro.

Temos vários tipos de medição, que podem ser verificados na coluna 'periodicidade'. Eles podem ser 'mensal', 'bimestral', 'trimestral', 'quadrimestral', 'semestral', ou 'anual'.

Então primeiro precisamos selecionar um subconjunto no qual o status é 'A', a coluna data deve ser verificada de acordo com a periodicidade. Por exemplo, se a periodicidade for mensal, o valor da coluna deve ser algum dia de maio, se for quadrimestral, deve ser num dos últimos 4 meses, se for semestral deve ser num dos últimos 6 meses.
Após fazer essa verificação, deve-se verificar se há valor na coluna 'medido'.
Se esses requisitos forem preenchidos, ok, o indicador ainda pode ser contado, se não, está fora.

Voce cita que o valor da coluna deve ser algum dia de algum mes de acordo com a periodicidade....

Como assim???? O_o Algum dia? QQ dia??

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vamos voltar ao post? :P

E vamos a primeira duvida:

 

 

Voce cita que o valor da coluna deve ser algum dia de algum mes de acordo com a periodicidade....

Como assim???? O_o Algum dia? QQ dia??

 

Sim, qualquer dia daquele mês pode haver a meta. Por exemplo: um indicador pode ter sido cadastrado dia 06/05, outro dia 08/05, outro 14/05. Pra mim o dia tanto faz. O que me importa é o mês.

 

Tentei fazer um frankenstein aqui. Mesmo que horrível parece funcionar para o mensal, agora preciso fazer para as demais periodicidades. E aceito sugestões para melhorar o meu:

 

 

-- Conta quantos indicadores cada programa possui com medição e todas as metas e com periodicidade mensal.
SELECT contagemMedicoesFuturas.Ano 'Ano', contagemMedicoesFuturas.Mes 'Mes', contagemMedicoesFuturas.programa 'programa', COUNT(contagemMedicoesFuturas.indicador) 'Total'
FROM (
		SELECT medicoesFuturasAgrupadas.Ano, medicoesFuturasAgrupadas.Mes, medicoesFuturasAgrupadas.programa, medicoesFuturasAgrupadas.acao, 
			   medicoesFuturasAgrupadas.indicador, medicoesFuturasAgrupadas.medicaoAtual, 
			   COUNT(medicoesFuturasAgrupadas.medicaoFutura) 'qtdMedicoesFuturas'
		FROM (
				-- Seleciona todas medições futura agrupadas.
				SELECT medicoesComMetas.Ano, medicoesComMetas.Mes, medicoesComMetas.programa, medicoesComMetas.acao, 
						 medicoesComMetas.indicador, medicoesComMetas.medicaoAtual, medicoesComMetas.medicaoFutura
				FROM (
						-- Busca as medições futuras (metas) com periodicidade mensal,
						-- que tenham uma medição atual atualizada.
						-- Ajusta todas as datas para poder agrupar alguma que eventualmente esteja no mesmo mês.
						SELECT medicaoAtual.Ano, medicaoAtual.Mes, medicaoAtual.programa, medicaoAtual.acao, medicaoAtual.indicador,
							   DATETIMEFROMPARTS(YEAR(medicaoFutura.data),MONTH(medicaoFutura.data),1,0,0,0,0) 'medicaoFutura', 
							   DATETIMEFROMPARTS(YEAR(medicaoAtual.data),MONTH(medicaoAtual.data),1,0,0,0,0) 'medicaoAtual'
						FROM medicoes as medicaoFutura
							 RIGHT JOIN
							 (
								SELECT medicaoAtual.Ano, medicaoAtual.Mes, medicaoAtual.programa, medicaoAtual.acao, medicaoAtual.indicador, 
									   medicaoAtual.periodicidade, medicaoAtual.data, medicaoAtual.medido
								FROM medicoes as medicaoAtual
								WHERE UPPER(LTRIM(RTRIM(medicaoAtual.verificado))) = 'SIM'
								  AND UPPER(LTRIM(RTRIM(medicaoAtual.tipoAcao))) = 'CORRENTES'
								  AND UPPER(LTRIM(RTRIM(medicaoAtual.status))) = 'A'
								  AND UPPER(LTRIM(RTRIM(medicaoAtual.periodicidade))) = 'MENSAL'
								  -- Medido diferente de zero ou justificado
								  AND (medicaoAtual.medido <> 0 OR ( medicaoAtual.medido = 0 AND ((LTRIM(RTRIM(medicaoAtual.acaoIndicador)) <> '') OR (LTRIM(RTRIM(medicaoAtual.analiseIndicador)) <> '')) ) )
								  -- Deve ter sua medição no máximo no mês anterior 
								  AND DATETIMEFROMPARTS(YEAR(medicaoAtual.data),MONTH(medicaoAtual.data),1,0,0,0,0) >= 
										DATEADD(MONTH, -1, DATETIMEFROMPARTS(medicaoAtual.Ano, medicaoAtual.Mes, 1,0,0,0,0))
								GROUP BY medicaoAtual.Ano, medicaoAtual.Mes, medicaoAtual.programa, medicaoAtual.acao, medicaoAtual.indicador, 
									   medicaoAtual.periodicidade, medicaoAtual.data, medicaoAtual.medido
							 ) as medicaoAtual
							 ON (medicaoAtual.Ano = medicaoFutura.Ano AND medicaoAtual.Mes = medicaoFutura.Mes AND 
								 medicaoAtual.programa = medicaoFutura.programa AND medicaoAtual.acao = medicaoFutura.acao AND medicaoAtual.indicador = medicaoFutura.indicador)
						WHERE UPPER(LTRIM(RTRIM(medicaoFutura.verificado))) = 'SIM'
						  AND UPPER(LTRIM(RTRIM(medicaoFutura.tipoAcao))) = 'CORRENTES'
						  AND UPPER(LTRIM(RTRIM(medicaoFutura.status))) = 'F'
						  AND UPPER(LTRIM(RTRIM(medicaoFutura.periodicidade))) = 'MENSAL'
						  -- Meta diferente de zero ou justificada
						  AND (medicaoFutura.meta <> 0 OR ( medicaoFutura.meta = 0 AND ((LTRIM(RTRIM(medicaoFutura.acaoIndicador)) <> '') OR (LTRIM(RTRIM(medicaoFutura.analiseIndicador)) <> '')) ) )
						GROUP BY medicaoAtual.Ano, medicaoAtual.Mes, medicaoAtual.programa, medicaoAtual.acao, medicaoAtual.indicador,
								 medicaoAtual.data,medicaoFutura.data
					) as medicoesComMetas
				GROUP BY medicoesComMetas.Ano, medicoesComMetas.Mes, medicoesComMetas.programa, medicoesComMetas.acao, 
						 medicoesComMetas.indicador, medicoesComMetas.medicaoAtual, medicoesComMetas.medicaoFutura
			) as medicoesFuturasAgrupadas
		GROUP BY medicoesFuturasAgrupadas.Ano, medicoesFuturasAgrupadas.Mes, medicoesFuturasAgrupadas.programa, medicoesFuturasAgrupadas.acao, 
				 medicoesFuturasAgrupadas.indicador, medicoesFuturasAgrupadas.medicaoAtual
	) as contagemMedicoesFuturas
	-- A quantidade de medições futuras deve totalizar o restante de meses do ano
WHERE contagemMedicoesFuturas.qtdMedicoesFuturas >= (12 - MONTH(contagemMedicoesFuturas.medicaoAtual))
GROUP BY contagemMedicoesFuturas.Ano, contagemMedicoesFuturas.Mes, contagemMedicoesFuturas.programa

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como que esta o plano de execução desta sua consulta? a volumetria é mto grande?

Eu acabei de criar uma tabela para tentar entender o que precisa rs

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como que esta o plano de execução desta sua consulta? a volumetria é mto grande?

Eu acabei de criar uma tabela para tentar entender o que precisa rs

Desculpe a ignorância, mas o que seria a volumetria?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quantidade de registros envolvidos no processo... por exemplo, mas tabelas tem entre 1 milhao e 1milhao e meio de registros ou 50 mil?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quantidade de registros envolvidos no processo... por exemplo, mas tabelas tem entre 1 milhao e 1milhao e meio de registros ou 50 mil?

 

Atualmente a tabela está com 334.224 registros. Na última entrada de dados foram inseridos 12 mil registros, que creio que seja a média de entrada de dados mensal.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou nesta parte:

 


Essas 3 linhas estão agrupadas pelo ano 2014, mês 6, programa CIDADE DA PARTICIPAÇÃO, ação AÇÕES DE POLÍTICAS SOCIAIS, indicador Ações de Empoderamento Local da Comunidade Santo André.

Ele é um indicador quadrimestral. É verificado e seu tipo de ação é corrente. OK, ele entra nesses requisitos.
A medição atual está em Abril. Como é quadrimestral, está valendo.
Ele possui duas linhas com metas no futuro (Agosto e Dezembro). Então esse indicador entra para aquela contagem final. Mas caso não tivesse dezembro, por exemplo, já não entraria.

Não entendi nadinha das tres tinhas que citou =\

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.