2010-12-07 26 views
1

Je dois produire un rapport indiquant le nombre de codes promotionnels particuliers utilisés au cours d'une semaine donnée. Exemple de structure de tableau:Le moyen le plus efficace dans MySQL pour récupérer des valeurs dans une semaine donnée?

CREATE TABLE `user_promo_codes` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `user_id` bigint(20) unsigned NOT NULL, 
    `promo_code` longtext NOT NULL, 
    `last_updated` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
) 

Ce que je veux, c'est un décompte de chaque code promo particulier utilisé dans une semaine donnée. Ce que j'ai en ce moment:

SELECT promo_code, count(*) AS count 
FROM user_promo_codes 
WHERE last_updated BETWEEN 
    FROM_UNIXTIME(# one week ago 
     UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 7 DAY)) - TIME_TO_SEC(NOW()) 
    ) 
    AND 
    FROM_UNIXTIME(
     UNIX_TIMESTAMP(NOW()) - TIME_TO_SEC(NOW()) 
    ) 
GROUP BY value 

Existe-t-il un moyen plus efficace de le faire?

+0

Vous voulez * vraiment * faire du champ last_updated un index. :-) –

Répondre

1

Pour les types de données que vous avez affichés, cela devrait fonctionner correctement pour la semaine précédant maintenant.

SELECT promo_code, COUNT(*) AS count 
FROM user_promo_codes 
WHERE last_updated BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND NOW() 
GROUP BY promo_code 

apartés:

  • L'utilisation d'un LONGTEXT pour la promo_code assurera une table temporaire sur le disque. Probablement préférable de faire un VARCHAR(N).
  • Comme middaparka noté, un index sur last_updated deviendra inestimable que la table se développe.

Mise à jour

Avec NOW() -> le plus récent Wedneday @00:00:00.

SELECT promo_code, COUNT(*) AS count 
FROM user_promo_codes 
WHERE last_updated BETWEEN 
DATE_SUB(CONCAT(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE())+5 DAY) ,' 00:00:00'), INTERVAL 7 DAY) 
AND 
CONCAT(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE())+5 DAY) ,' 00:00:00') 
GROUP BY promo_code 

Ce qui est juste au-dessus avec

CONCAT(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE())+5 DAY) ,' 00:00:00') 

dans les troqué NOW() s.

+0

C'est en grande partie à ce dont j'ai besoin, mais il est important que les extrémités de cette clause BETWEEN soient comme je l'ai spécifié ci-dessus. Je ne peux pas garantir que le script sera exécuté de telle sorte que NOW() sera toujours minuit mercredi matin. –