Faccruz 0 Denunciar post Postado Setembro 17, 2009 Boa tarde, Possuo uma tabela na seguinte estrutura idMetas Int AutoIncremento MesAno Varchar(10) Atingiu Char(1) idFuncionario Int Nessa Tabela o funcionario insere se ele atingiu ou não a meta estipulada para o mês. Preciso saber como retornar o(s) mês(es) que ele não incluiu e obrigar a ele incluir o mês faltante antes de continuar. Estipulamos aqui um inicio para a digitação dessas metas (Agosto de 2008) ou, caso a data de admissão desse funcionario for maior que a estipulada (agosto/2008), comece a vigorar a data de admissão. Ele pode incluir os meses anteriores e/ou posteriores a data vigente na CPU. Espero ter sido claro. Compartilhar este post Link para o post Compartilhar em outros sites
Eclesiastes 2 Denunciar post Postado Setembro 18, 2009 Você pode até criar o "calendário" na query, mas terá que fazer isso manualmente, mas precisamente em relação aos anos. (Embora você possa especificar vários e vários e não ter que se preocupar com eles tão cedo :D) Fiz um simples teste com esses dados: mysql> select * from metas; +---------+--------+---------+---------------+ | idmetas | mesano | atingiu | idfuncionario | +---------+--------+---------+---------------+ | 1 | 082008 | S | 1 | | 2 | 102008 | S | 1 | | 3 | 092009 | S | 2 | +---------+--------+---------+---------------+ 3 rows in set (0.00 sec) Com a seguinte query: mysql> SELECT B.ANO, B.MES -> FROM ( -> SELECT * -> FROM ( -> SELECT 2008 ANO -> UNION -> SELECT 2009 -> ) ANOS, ( -> SELECT '01' MES -> UNION -> SELECT '02' -> UNION -> SELECT '03' -> UNION -> SELECT '04' -> UNION -> SELECT '05' -> UNION -> SELECT '06' -> UNION -> SELECT '07' -> UNION -> SELECT '08' -> UNION -> SELECT '09' -> UNION -> SELECT '10' -> UNION -> SELECT '11' -> UNION -> SELECT '12' -> ) MESES -> ) B -> LEFT JOIN metas A -> ON A.MESANO = CONCAT(B.MES, B.ANO) AND A.IDFUNCIONARIO = 1 -> WHERE CONCAT(B.ANO, B.MES) BETWEEN '200808' AND EXTRACT(YEAR_MONTH FROM CURDATE()) -> AND A.IDFUNCIONARIO IS NULL -> ORDER BY B.ANO, B.MES; +------+-----+ | ANO | MES | +------+-----+ | 2008 | 09 | | 2008 | 11 | | 2008 | 12 | | 2009 | 01 | | 2009 | 02 | | 2009 | 03 | | 2009 | 04 | | 2009 | 05 | | 2009 | 06 | | 2009 | 07 | | 2009 | 08 | | 2009 | 09 | +------+-----+ 12 rows in set (0.00 sec) Perceba que no caso, eu gero a combinação de mês e ano só para 2008 e 2009, e também defino o intervalo do mês inicial e final, talvez isto lhe atenda. Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 18, 2009 Você pode até criar o "calendário" na query, mas terá que fazer isso manualmente, mas precisamente em relação aos anos. (Embora você possa especificar vários e vários e não ter que se preocupar com eles tão cedo :D) Fiz um simples teste com esses dados: mysql> select * from metas; +---------+--------+---------+---------------+ | idmetas | mesano | atingiu | idfuncionario | +---------+--------+---------+---------------+ | 1 | 082008 | S | 1 | | 2 | 102008 | S | 1 | | 3 | 092009 | S | 2 | +---------+--------+---------+---------------+ 3 rows in set (0.00 sec) Com a seguinte query: mysql> SELECT B.ANO, B.MES -> FROM ( -> SELECT * -> FROM ( -> SELECT 2008 ANO -> UNION -> SELECT 2009 -> ) ANOS, ( -> SELECT '01' MES -> UNION -> SELECT '02' -> UNION -> SELECT '03' -> UNION -> SELECT '04' -> UNION -> SELECT '05' -> UNION -> SELECT '06' -> UNION -> SELECT '07' -> UNION -> SELECT '08' -> UNION -> SELECT '09' -> UNION -> SELECT '10' -> UNION -> SELECT '11' -> UNION -> SELECT '12' -> ) MESES -> ) B -> LEFT JOIN metas A -> ON A.MESANO = CONCAT(B.MES, B.ANO) AND A.IDFUNCIONARIO = 1 -> WHERE CONCAT(B.ANO, B.MES) BETWEEN '200808' AND EXTRACT(YEAR_MONTH FROM CURDATE()) -> AND A.IDFUNCIONARIO IS NULL -> ORDER BY B.ANO, B.MES; +------+-----+ | ANO | MES | +------+-----+ | 2008 | 09 | | 2008 | 11 | | 2008 | 12 | | 2009 | 01 | | 2009 | 02 | | 2009 | 03 | | 2009 | 04 | | 2009 | 05 | | 2009 | 06 | | 2009 | 07 | | 2009 | 08 | | 2009 | 09 | +------+-----+ 12 rows in set (0.00 sec) Perceba que no caso, eu gero a combinação de mês e ano só para 2008 e 2009, e também defino o intervalo do mês inicial e final, talvez isto lhe atenda. Não entendi muito bem como verifico o mes que o funcionario esqueceu de digitar. A minha dúvida é saber qual mês/ano o funcionario pulou ou esqueceu de digitar. Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 18, 2009 Deixa tentar explicar melhor como faço para percorrer uma tabela identificando se o funcionario esqueceu/pulou algum registro? Estrutura da tabela idMetas int AutoInc MesAno VarChar(10) Atingiu Char(1) idFuncionario int Ex. de dados gravados idMetas MesAno Atingiu idFuncionario 1 2008-08-01 S 115 2 2008-09-01 S 115 3 2008-11-01 N 115 nesse exemplo, deveria acusar que ele esqueceu/pulou o mês 10/2008. Obs. Gravo todas as datas como sendo o dia 1 de cada mês Como faço para resolver isso? Compartilhar este post Link para o post Compartilhar em outros sites
Eclesiastes 2 Denunciar post Postado Setembro 19, 2009 Aproveitando a sua questão, postei em meu blog uma pequena explicação do que eu fiz para resolver, inclusive melhorei a abordagem levando em conta as suas informações a respeito da data. Dê uma olhada: http://felipe.c2zlabs.com/identificando-intervalos-entre-datas-no-mysql Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 19, 2009 Aproveitando a sua questão, postei em meu blog uma pequena explicação do que eu fiz para resolver, inclusive melhorei a abordagem levando em conta as suas informações a respeito da data. Dê uma olhada: http://felipe.c2zlabs.com/identificando-intervalos-entre-datas-no-mysql Vou testar na segunda-feira daí posto o resultado Valeu! Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Aproveitando a sua questão, postei em meu blog uma pequena explicação do que eu fiz para resolver, inclusive melhorei a abordagem levando em conta as suas informações a respeito da data. Dê uma olhada: http://felipe.c2zlabs.com/identificando-intervalos-entre-datas-no-mysql Vou testar na segunda-feira daí posto o resultado Valeu! Bom dia Amigo, Fiz o teste aqui, mas não está funcionando perfeitamente, alem de exibir a data que falta, esta exibindo também a data já cadastrada, onde posso fazer alteração? Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Amigo... tem um erro nesse SQL que você montou, caso algum funcionário tenha incluido o mês que falta para outro (com seus proprios códigos), ele não me retorna para esse que está faltando. Tentei incluir uma clausula para filtrar o código, mas sem sucesso. Compartilhar este post Link para o post Compartilhar em outros sites
giesta 29 Denunciar post Postado Setembro 21, 2009 Partindo do principio q pelo menos 1 funcionario lembrou de fazer algum mes (nao houve um esquecimento de todos de algum mes) daria pra fazer assim, de maneira simples: select t.funcionario, m.mes from (select distinct mesano mes from tabela)m , Left join tabela t ON m.mes = t.mesano where t.mesano is null Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Partindo do principio q pelo menos 1 funcionario lembrou de fazer algum mes (nao houve um esquecimento de todos de algum mes) daria pra fazer assim, de maneira simples: select t.funcionario, m.mes from (select distinct mesano mes from tabela)m , Left join tabela t ON m.mes = t.mesano where t.mesano is null Onde eu encaixo essa SQL? Compartilhar este post Link para o post Compartilhar em outros sites
giesta 29 Denunciar post Postado Setembro 21, 2009 Essa SQL te traz todos os funcionarios com os meses q eles esqueceram de digitar Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Essa SQL te traz todos os funcionarios com os meses q eles esqueceram de digitar Entendi, mas pra isso teria que ter os todos os meses cadastrados na base, me corrija se estiver errado. No meu cadastro, o funcionario seleciona o Mês e o Ano que deseja incluir, e nisso ele poderia pular/esquecer de algum. Compartilhar este post Link para o post Compartilhar em outros sites
giesta 29 Denunciar post Postado Setembro 21, 2009 Partindo do principio q pelo menos 1 funcionario lembrou de fazer algum mes (nao houve um esquecimento de todos de algum mes) daria pra fazer assim, de maneira simples: Ou seja a nao ser q você tenha uma equipe imbecis, sempre alguem vai ter lembrado de colocar os meses, pode ser q eles esqueceram um mes ou outro, mas TODOS esquecerem algum mes nao tem como, a consulta se baseia nisso, entendeu? Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Partindo do principio q pelo menos 1 funcionario lembrou de fazer algum mes (nao houve um esquecimento de todos de algum mes) daria pra fazer assim, de maneira simples: Ou seja a nao ser q você tenha uma equipe imbecis, sempre alguem vai ter lembrado de colocar os meses, pode ser q eles esqueceram um mes ou outro, mas TODOS esquecerem algum mes nao tem como, a consulta se baseia nisso, entendeu? Mas são vários funcionarios, códigos de acesso diferentes, várias lojas (70 ao todo), ou seja, são mais de 200 códigos, não estou dizendo que TODOS irão esquecer, mas no minimo, chutando baixo, 10 esqueceram de digitar um ou outro, e é essa a minha dúvida. O tópico do Eclesiastes, resolveu qndo existe apenas UM (1) funcionario cadastrado na tabela METAS, com mais, ele se perde. Agora essa equipe de imbecis, como você disse, são usuários finais e muitos com mais de 20 anos de empresa, então tudo pode acontecer. Me lembro na época da faculdade, um dos orientadores me disse, "Qndo criar um sistema pense em um usuário que nunca viu um computador na frente, e monte um sistema para esse usuário." Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Aproveitando a sua questão, postei em meu blog uma pequena explicação do que eu fiz para resolver, inclusive melhorei a abordagem levando em conta as suas informações a respeito da data. Dê uma olhada: http://felipe.c2zlabs.com/identificando-intervalos-entre-datas-no-mysql Amigo, alguma posição? Compartilhar este post Link para o post Compartilhar em outros sites
Eclesiastes 2 Denunciar post Postado Setembro 21, 2009 Olá, quando eu montei a query, eu pensei que você fosse rodar apenas para obter as informações acerca de um único usuário. Enfim, levando em consideração que a primeira e a última data marcada do usuário delimita a busca pelo buracos, com uma pequena alteração na query que eu fiz, obtemos o resultado: mysql> select * from metas; +---------+------------+---------+---------------+ | idmetas | mesano | atingiu | idfuncionario | +---------+------------+---------+---------------+ | 1 | 2009-01-01 | S | 1 | | 2 | 2009-02-01 | S | 1 | | 3 | 2009-04-01 | S | 1 | | 4 | 2009-05-01 | S | 1 | | 5 | 2009-08-01 | S | 1 | | 6 | 2008-02-01 | S | 2 | | 7 | 2008-05-01 | S | 2 | +---------+------------+---------+---------------+ 7 rows in set (0.00 sec) mysql> SELECT X.idfuncionario, DATE_ADD(X.INICIO, INTERVAL Y.N MONTH) DATA -> FROM ( -> SELECT idfuncionario, MIN(mesano) inicio, MAX(mesano) fim -> FROM metas -> GROUP BY idfuncionario -> ) X -> JOIN ( -> SELECT A.A+B.B+1 N -> FROM (SELECT 0 A UNION ALL -> SELECT 1 UNION ALL -> SELECT 2 UNION ALL -> SELECT 3 UNION ALL -> SELECT 4 UNION ALL -> SELECT 5 UNION ALL -> SELECT 6 UNION ALL -> SELECT 7 UNION ALL -> SELECT 8 UNION ALL -> SELECT 9) A, -> (SELECT 0 B UNION ALL -> SELECT 10 UNION ALL -> SELECT 20 UNION ALL -> SELECT 30 UNION ALL -> SELECT 40 UNION ALL -> SELECT 50 UNION ALL -> SELECT 60 UNION ALL -> SELECT 70 UNION ALL -> SELECT 80 UNION ALL -> SELECT 90) B -> ORDER BY 1 -> ) Y -> ON DATE_ADD(X.inicio, INTERVAL Y.N MONTH) < X.FIM -> LEFT JOIN metas M -> ON M.mesano = DATE_ADD(X.inicio, INTERVAL Y.N MONTH) -> AND M.idfuncionario = X.idfuncionario -> WHERE M.mesano IS NULL; +---------------+------------+ | idfuncionario | DATA | +---------------+------------+ | 2 | 2008-03-01 | | 1 | 2009-03-01 | | 2 | 2008-04-01 | | 1 | 2009-06-01 | | 1 | 2009-07-01 | +---------------+------------+ 5 rows in set (0.00 sec) Correto!? Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 21, 2009 Olá, quando eu montei a query, eu pensei que você fosse rodar apenas para obter as informações acerca de um único usuário. Enfim, levando em consideração que a primeira e a última data marcada do usuário delimita a busca pelo buracos, com uma pequena alteração na query que eu fiz, obtemos o resultado: mysql> select * from metas; +---------+------------+---------+---------------+ | idmetas | mesano | atingiu | idfuncionario | +---------+------------+---------+---------------+ | 1 | 2009-01-01 | S | 1 | | 2 | 2009-02-01 | S | 1 | | 3 | 2009-04-01 | S | 1 | | 4 | 2009-05-01 | S | 1 | | 5 | 2009-08-01 | S | 1 | | 6 | 2008-02-01 | S | 2 | | 7 | 2008-05-01 | S | 2 | +---------+------------+---------+---------------+ 7 rows in set (0.00 sec) mysql> SELECT X.idfuncionario, DATE_ADD(X.INICIO, INTERVAL Y.N MONTH) DATA -> FROM ( -> SELECT idfuncionario, MIN(mesano) inicio, MAX(mesano) fim -> FROM metas -> GROUP BY idfuncionario -> ) X -> JOIN ( -> SELECT A.A+B.B+1 N -> FROM (SELECT 0 A UNION ALL -> SELECT 1 UNION ALL -> SELECT 2 UNION ALL -> SELECT 3 UNION ALL -> SELECT 4 UNION ALL -> SELECT 5 UNION ALL -> SELECT 6 UNION ALL -> SELECT 7 UNION ALL -> SELECT 8 UNION ALL -> SELECT 9) A, -> (SELECT 0 B UNION ALL -> SELECT 10 UNION ALL -> SELECT 20 UNION ALL -> SELECT 30 UNION ALL -> SELECT 40 UNION ALL -> SELECT 50 UNION ALL -> SELECT 60 UNION ALL -> SELECT 70 UNION ALL -> SELECT 80 UNION ALL -> SELECT 90) B -> ORDER BY 1 -> ) Y -> ON DATE_ADD(X.inicio, INTERVAL Y.N MONTH) < X.FIM -> LEFT JOIN metas M -> ON M.mesano = DATE_ADD(X.inicio, INTERVAL Y.N MONTH) -> AND M.idfuncionario = X.idfuncionario -> WHERE M.mesano IS NULL; +---------------+------------+ | idfuncionario | DATA | +---------------+------------+ | 2 | 2008-03-01 | | 1 | 2009-03-01 | | 2 | 2008-04-01 | | 1 | 2009-06-01 | | 1 | 2009-07-01 | +---------------+------------+ 5 rows in set (0.00 sec) Correto!? Realmente irei listar apenas de um funcionário, o erro que menciono é se um determinado usuário (ex.1) esqueceu de preencher o mês 10/2008 e o usuário 2 preencheu essa data, ela não retorna para o usuário 1 que faltou essa data, tendo em vista que são cadastros diferentes. Compartilhar este post Link para o post Compartilhar em outros sites
Eclesiastes 2 Denunciar post Postado Setembro 21, 2009 Ok. Eu havia entendido errado, tinha entendido que a primeira e última data do usuário delimitaria a busca. Levando então em conta que a primeira e última de todos os usuários delimitará a busca, você poderia fazer algo como: mysql> SELECT DATE_ADD(X.INICIO, INTERVAL Y.N MONTH) DATA -> FROM ( -> SELECT MIN(mesano) inicio, MAX(mesano) fim -> FROM metas -> ) X -> JOIN ( -> SELECT A.A+B.B+1 N -> FROM (SELECT 0 A UNION ALL -> SELECT 1 UNION ALL -> SELECT 2 UNION ALL -> SELECT 3 UNION ALL -> SELECT 4 UNION ALL -> SELECT 5 UNION ALL -> SELECT 6 UNION ALL -> SELECT 7 UNION ALL -> SELECT 8 UNION ALL -> SELECT 9) A, -> (SELECT 0 B UNION ALL -> SELECT 10 UNION ALL -> SELECT 20 UNION ALL -> SELECT 30 UNION ALL -> SELECT 40 UNION ALL -> SELECT 50 UNION ALL -> SELECT 60 UNION ALL -> SELECT 70 UNION ALL -> SELECT 80 UNION ALL -> SELECT 90) B -> ORDER BY 1 -> ) Y -> ON DATE_ADD(X.inicio, INTERVAL Y.N MONTH) <= X.FIM -> LEFT JOIN metas M -> ON M.mesano = DATE_ADD(X.inicio, INTERVAL Y.N MONTH) -> AND M.idfuncionario = 2 -> WHERE M.mesano IS NULL; +------------+ | DATA | +------------+ | 2008-03-01 | | 2008-04-01 | | 2008-06-01 | | 2008-07-01 | | 2008-08-01 | | 2008-09-01 | | 2008-10-01 | | 2008-11-01 | | 2008-12-01 | | 2009-01-01 | | 2009-02-01 | | 2009-03-01 | | 2009-04-01 | | 2009-05-01 | | 2009-06-01 | | 2009-07-01 | | 2009-08-01 | +------------+ 17 rows in set (0.01 sec) Compartilhar este post Link para o post Compartilhar em outros sites
Faccruz 0 Denunciar post Postado Setembro 22, 2009 Muito Obrigado! Funcionou do jeito que eu queria, apenas fazendo uma alteração! Segue a alteração. SELECT DATE_ADD(X.INICIO, INTERVAL Y.N MONTH) DATA FROM (SELECT MIN(mesano) inicio, MAX(mesano) fim FROM metas where idFuncionario = 118 --> Acrescentei essa linha) X JOIN ( SELECT A.A+B.B+1 N FROM (SELECT 0 A UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) A, (SELECT 0 B UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30 UNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60 UNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90) B ORDER BY 1 ) Y ON DATE_ADD(X.inicio, INTERVAL Y.N MONTH) <= X.FIM LEFT JOIN metas M ON M.mesano = DATE_ADD(X.inicio, INTERVAL Y.N MONTH) AND M.idfuncionario = 118 WHERE M.mesano IS NULL; Compartilhar este post Link para o post Compartilhar em outros sites
Eclesiastes 2 Denunciar post Postado Setembro 22, 2009 Errr, bem observado! hehe, esqueci deste detalhe. Compartilhar este post Link para o post Compartilhar em outros sites