Question

I need to produce a report that provides the count of each particular promotional code used within a particular week. Example table structure:

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`),
)

What I want is a count of each particular promo code used in a given week. What I have right now:

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

Is there a more efficient way of doing this?

Was it helpful?

Solution

For the data types you've shown, this should work fine for the week previous to now.

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

Asides:

  • Using a LONGTEXT for the promo_code will ensure a temp table on disk. Likely best to make that a VARCHAR(N).
  • As middaparka noted, an index on last_updated will become invaluable as the table grows.

Update

With NOW() -> the most recent 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

Which is just the above with

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

swapped in for the NOW()s.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top