Question

I have two tables. Here are some fields that will be used in query.

tgc_sales (code,sale_date_time, order_status)

tgc_sales_items (sales_code, quantity, product_name, product_code)

What I want is to get the most sold products within a specific period of time (say a week, a month etc).

What I tried so far:

SELECT SUM(tsi.quantity) AS quantity, tsi.product_name AS product_name
FROM tgc_sales_items tsi 
JOIN tgc_sales ts ON ts.code = tsi.sales_code
WHERE DATE(ts.sale_date_time)>='2014-05-01'
    AND ts.order_status='Completed' 
GROUP BY tsi.product_code
ORDER BY quantity DESC LIMIT 10

Obviously, the query is wrong and it is giving me unexpected result. When I ignore the JOIN and WHERE clause it shows me the most sold products but I need it for when the sales was made in a specific period and I can't figure out how to do it.

Was it helpful?

Solution

The query looks right, assuming that code is a unique (or primary) key on the tgc_sales table, and sales_code is a foreign key reference to that column.

The use of the DATE() function seems a bit odd.

If the sales_date_time column has a datatype of DATE, DATETIME, or TIMESTAMP, then the DATE() function isn't needed, and it's not desirable because it disables MySQL's ability to use an index range scan to satisfy the predicate.

If the sales_date_time is character, and your intent is to convert the character into a DATE, you'd use the STR_TO_DATE() function. But you don't really want to store sales_date_time as a character string.

If that's a DATETIME column, you'd do something like this:

WHERE ts.sale_date_time >= '2014-05-01'
  AND ts.sale_date_time <  '2014-06-01'

If it's a character column in a non-canonical format (e.g. 'mm/dd/yyyy hh:mi:ss'), then you could do something like:

WHERE STR_TO_DATE(ts.sale_date_time,'%m/%d/%Y %h:%i:%s') >= '2014-05-01'
  AND STR_TO_DATE(ts.sale_date_time,'%m/%d/%Y %h:%i:%s') <  '2014-06-01'

(But you don't really want to store a date time value in a character string; you want to use one of the MySQL datatypes like DATETIME.)

If you're storing a unix-style timestamp "seconds since the beginning of an era", then you'd want to do the comparison against the native column values. You could do something like this:

WHERE ts.sale_date_time >= UNIX_TIMESTAMP('2014-05-01')
  AND ts.sale_date_time <  UNIX_TIMESTAMP('2014-06-01')

...though you'd really prefer to use the same library used to do the conversion when the values were stored, and do the query more like this:

WHERE ts.sale_date_time >= 1398902400
  AND ts.sale_date_time <  1401580800

OTHER TIPS

Your group by seems suspicious. It includes product_code column which is not in the select clause.

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