MySQL PHP select rows count in date range - php

I have a MySQL table for product orderings named TABLE1.
Date means the date purchase has been made
The table has other columns that currently have no influence.
PRODUCT_ID | DATE | other columns
3 |2018-02-01 | other values
3 |2018-02-03 | other values
3 |2018-02-07 | other values
3 |2018-02-07 | other values
3 |2018-03-02 | other values
I know that the first time the product 3 has been ordered, is 2018-02-01
SELECT DATE FROM TABLE1 WHERE PRODUCT_ID = '3' ORDER BY DATE ASC LIMIT 1
How do I select count of product orderings per day within range of 2018-02-01 and 2019-03-16 (today) so that I could get a table like that:
DATE | ORDERS_PER_DAY
2018-02-01 | 1
2018-02-02 | 0
2018-02-03 | 1
...
2018-02-07 | 2
...
2018-03-02 | 1
...
2018-03-15 | 0
2018-03-16 | 0
Thanks for help!

You can simply use GROUP BY clause to do it.
SELECT `DATE`, COUNT(`PRODUCT_ID`) AS ORDERS_PER_DAY
FROM TABLE1
WHERE `DATE` BETWEEN '2018-02-01' AND CURDATE()
GROUP BY `DATE`
This query will result in filtering the records on your required date range and then grouping it by each day where there is data.

My syntax may not be exactly correct, but could you try something like this using the GROUP BY clause.
SELECT DATE, COUNT(*) AS ORDERS_PER_DAY
FROM TABLE1
GROUP BY DATE, PRODUCT_ID
HAVING PRODUCT_ID = '3'
you can read more about this here: https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html

Related

Joining a calendar table to a sales table to get total sales for every day in a specified range

I have a 'sales' table called phpbb_sold which records each 'sale' as a row.
I am able to use a WHERE clause with the uitemid field to select one particular item in the sales records, as seen below:
SELECT uitemid, locktime, migrated_sold FROM phpbb_sold WHERE uitemid=342;
+---------+------------+---------------+
| uitemid | locktime | migrated_sold |
+---------+------------+---------------+
| 342 | 1632523854 | 1 |
| 342 | 1634239244 | 1 |
| 342 | 1634240072 | 1 |
| 342 | 1636367271 | 1 |
+---------+------------+---------------+
uitemid = number that identifies this as a sale of X item. locktime = UNIX timestamp that shows the datetime that the item was sold. migrated_sold = the quantity of the item sold. So this is nice, I have a table that keeps a record of each sale as it happens.
What I want to achieve though, is a record of the total number of sales of this item type, for each day in a 6 month period spanning back from the current date, and including each day regardless of whether a sale was made or not. So the desired output of my query would be:
SELECT (the query I want goes here) and returns the following rows...;
+------------+------------+
| caldate | sold_total |
+------------+------------+
| 2021-09-23 | 2 |
| 2021-09-24 | 0 |
| 2021-09-25 | 1 |
| 2021-09-26 | 0 |
| 2021-09-27 | 0 |
| 2021-09-28 | 1 |
+------------+------------+
Note that each day is included as a row in the results, even where the sales total for that day is 0. I read that to do this, I would be required to create a calendar table with one column and all the days I want as rows, so I went ahead and did that:
SELECT caldate FROM phpbb_calendar;
+------------+
| caldate |
+------------+
| 2021-09-23 |
| 2021-09-24 |
| 2021-09-25 |
| 2021-09-26 |
| 2021-09-27 |
| 2021-09-28 |
+------------+
Now all that remains is for me to make the query. I need to somehow return all the rows from the phpbb_calendar table, joining the data from sum() (?) of the total migrated_sold for those days where exists, and a 0 where no sales took place.
I anticipated some issues with the UNIX timestamp, but it's okay because I am able to get caldate and locktime fields to be the same format by using from_unixtime(locktime, '%Y-%m-%d'), so both dates will be in the YYYY-MM-DD format for comparison.
Please could someone help me with this. I've gotten so close every time but it seems that everyone else's request is only slightly different from mine, so existing questions and answers have not been able to satisfy my requirements.
End goal is to use a JS chart library (AnyChart) to show a line graph of the number of sales of the item over time. But to get there, I first need to provide it with the query necessary for it to display that data.
Thanks
Update
Using this query:
SELECT c.caldate, u.uitemid, sum(v.migrated_sold) as total_sales
from phpbb_calendar c cross join
(select distinct uitemid from phpbb_sold) u left join
phpbb_sold v
on c.caldate = from_unixtime(v.locktime, '%Y-%m-%d') WHERE u.uitemid = 39 and c.caldate <= curdate() GROUP BY c.caldate ORDER BY c.caldate;
Returns:
But as you can see, it's just tallying up the total number of sales ever made or something - its clearly incrementing in a way I don't understand.
I don't want it to do that - I want it to count the number of total sales on each day individually. The results should look like this:
So that what is returned is basically a 'histogram' of sales, if any occurred, including 'empty' days where there were no sales (so these empty days must still be returned as rows).
SELECT c.caldate, u.uitemid, COALESCE(SUM(v.migrated_sold), 0) AS total_sales
FROM phpbb_calendar c
CROSS JOIN (SELECT DISTINCT uitemid FROM phpbb_sold WHERE uitemid = 37) u
LEFT JOIN phpbb_sold v
ON v.locktime BETWEEN UNIX_TIMESTAMP(TIMESTAMP(c.caldate)) AND UNIX_TIMESTAMP(TIMESTAMP(c.caldate, '23:59:59'))
AND u.uitemid = v.uitemid
WHERE c.caldate BETWEEN CURDATE() - INTERVAL 6 MONTH AND CURDATE()
GROUP BY c.caldate, u.uitemid
ORDER BY c.caldate;
N.B. I have changed your join to use the unix_timestamp as it should be more efficient and it can use any existing index on locktime
check this out:
select id, d, sum(s) from (
select U.id, d, 0 s from (
select adddate(current_date(),-rows.r) d from (
select (#row_number := #row_number + 1) r
from information_schema.columns,
(SELECT #row_number := 0) AS x
limit 200
) rows
) dates,
(SELECT distinct uitemid id FROM `phpbb_sold`) U
where d > adddate(current_date(), interval -6 month)
union
select uitemid, date(from_unixtime(locktime)),sum(migrated_sold)
from `phpbb_sold`
group by uitemid, date(from_unixtime(locktime))
) sales_union
group by id, d
order by id, d;
see dbfiddle
no need for calendar table

Count different days of the same month

I select specific rows from the MySQL database and get the following list:
2017-07-28
2017-07-28
2017-07-28
2017-07-28
2017-07-31
2017-07-31
2017-08-01
2017-08-01
2017-08-02
2017-08-02
2017-08-02
2017-08-03
2017-08-04
I would like to count how many days per month were different, in this case I would like to get the following result:
2017-07: 2 different days
2017-08: 4 different days
I tried to do this with the help of arrays but unsuccessfully.
Using:
SELECT DATE_FORMAT(date_col, '%Y-%m') AS year_month
, COUNT(DISTINCT DAY(date_col)) AS cnt
FROM your_table
GROUP BY DATE_FORMAT(date_col, '%Y-%m');
How it works:
first create group based on year-month part
use aggreagate function COUNT to count occurences in each group
DISTINCT to get only different values of day in month
E.g.
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,dt DATE NOT NULL
);
INSERT INTO my_table (dt) VALUES
('2017-07-28'),
('2017-07-28'),
('2017-07-28'),
('2017-07-28'),
('2017-07-31'),
('2017-07-31'),
('2017-08-01'),
('2017-08-01'),
('2017-08-02'),
('2017-08-02'),
('2017-08-02'),
('2017-08-03'),
('2017-08-04');
SELECT DATE_FORMAT(dt,'%Y-%m') yearmonth, COUNT(DISTINCT dt) total FROM my_table GROUP BY yearmonth;
+-----------+-------+
| yearmonth | total |
+-----------+-------+
| 2017-07 | 2 |
| 2017-08 | 4 |
+-----------+-------+

How to fetch multiple duplicate value count in sql

i have database in which user device id and device registerd date (cr_date) stored i want to fetch list of total count of registerd devices on same day with date wise
Here below display table structure
device_ID | cr_date
--------------------
1 | 2016-06-02 18:02:13
2 | 2016-06-02 18:03:58
3 | 2016-06-02 18:04:11
4 | 2016-06-03 18:04:33
5 | 2016-06-03 18:04:33
6 | 2016-06-04 18:04:44
and i want below result
count | date
---------------------------------
3 | 2016-06-02
2 | 2016-06-03
1 | 2016-06-04
i used below query but dosent get success
SELECT device_type, count(*) AS duplicate_count
FROM (
SELECT device_type FROM tbl_app_deviceregister
GROUP BY device_type HAVING COUNT(device_type) > 0
) AS t
Did you want this;)
SELECT count(1) as `count`, date_format(cr_date, '%Y-%m-%d') as `date`
FROM tbl_app_deviceregister
GROUP BY `date`
ORDER BY `count` DESC
You should GROUP BY date value, not by device:
SELECT CAST(cr_date AS DATE) AS `date`, COUNT(device_id)
FROM tbl_app_deviceregister
GROUP BY CAST(cr_date AS DATE)
Your query doesn't seem to reference the same table structure that you've described, but from what I understand, would this work?
SELECT count(id), date_registered FROM (
SELECT
id,
DATE(FROM_UNIXTIME(cr_date)) as date_registered
FROM
tbl_app_deviceregister
) A GROUP BY date_registered
you group it by device_type which is wrong. try to group by date.
select COUNT(*) as count,CONVERT(date,cr_date) as date
from tbl_app_deviceregister
group by CONVERT(date,cr_date)

Count all unique records

I have a database with the following format:
myTable
productgroupID | productID | views | date
1 | 10 | 25 | 2013-05-23
4 | 105 | 15 | 2013-05-23
7 | 60 | 65 | 2013-05-23
7 | 60 | 55 | 2013-05-22
7 | 60 | 45 | 2013-05-21
Now I want to sum all views of a product in the moth May.
Result should be:
productgroupID | productID | viewed | month
7 | 60 | 165 | 2013-05-01
1 | 10 | 25 | 2013-05-01
4 | 105 | 15 | 2013-05-01
I tried the query below, but this gives me all views of a specific productgroupID. But I need the sum of the unique productgroupID & productID.
SELECT COUNT( views ) AS viewed, productgroupID FROM product_stats_daily GROUP BY productgroupID
If you want the views totaled, then you can use the sum() aggregate function and then you can group by the month and year for the date:
select productGroupId,
productId,
sum(views) viewed,
month(date) Month,
year(date) Year
from myTable
group by productGroupId, productId, month(date), year(date);
See SQL Fiddle with Demo
You could also use Date_Format to get the date in the format that you want:
select productGroupId,
productId,
sum(views) viewed,
DATE_FORMAT(date, '%Y-%m-01') date
from myTable
group by productGroupId, productId, DATE_FORMAT(date, '%Y-%m-01')
See SQL Fiddle with Demo
COUNT will count number of rows while SUM will sum up value of retrieved rows.
So your query becomes:
SELECT SUM( views ) AS viewed, productgroupID
FROM product_stats_daily
GROUP BY productgroupID
There's probably a more elegant way to force the date to the beginning of the month, but this should work:
SELECT
ProductGroupID,
ProductID,
SUM(views) AS viewed,
DATE_FORMAT(date, '%Y-%m-01') AS Month
FROM myTable
GROUP BY
ProductGroupID,
ProductID,
DATE_FORMAT(date, '%Y-%m-01')

SQL query to group by and order by timestamp

Hey guys, I've tried to get this right but I can't, maybe you can point me in the right direction
I have 3 columns, 'url_id', 'timestamp' and 'o'. I need to group by 'url_id' and sort by the most current timestamp.
table "example"
timestamp | url_id | o
----------------------------
2000 | 1 | 50
2007 | 1 | 70
2011 | 1 | 90
2001 | 2 | 20
2006 | 2 | 50
2009 | 2 | 40
2011 | 2 | 10
'o' is the value at the end I want. I was trying to do this with a subquery but kept getting the oldest value (tried order by, and had no luck).
What am I doing wrong? Is what I'm looking for actually require a subquery?
SELECT url_id
, MAX(timestamp) AS currentTS
FROM yourTable
GROUP BY url_id
ORDER BY currentTS DESC
Aftre you last explanation, I think you need to JOIN the above query to your original table, like this:
SELECT y.timestamp
, y.url_id
, y.o
FROM yourTable y
JOIN
( SELECT url_id
, MAX(timestamp) AS currentTS
FROM yourTable
GROUP BY url_id
) AS grp
ON grp.url_id = y.url_id
AND grp.currentTS = y.timestamp
ORDER BY y.timestamp DESC
Note: if there are two (or more) rows with same url_id and same timestamp, they'll both (or all) appear at the results.

Categories