Count different days of the same month - php

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 |
+-----------+-------+

Related

Select SUM "separately" for the past 30 days

I have a MySQL table which is as follows
------------------------------------------------
| id | user_id | day | value |
| INT(11) | INT(11) | INT(8) | DECIMAL(5,2) |
------------------------------------------------
Day is (Ymd) number like this: 20191012
I want to grab the SUM(value) for Today and the past 29 days separately (30 days, based on day column)
I thought of a loop like this
for($i=0;$i<=30;$i++)
{
$query = "SELECT SUM(value) FROM table WHERE day=".date('Ymd', strtotime("-{$i} days"));
}
But how can I achieve this more efficiently?
Any help is appreciated.
You could use Group By to fetch it with a single MySQL-Query
SELECT day, SUM(value) FROM table GROUP BY day WHERE day >= ".date('Ymd', strtotime("-29 days"));
It should work because your day field is a number and will increase everyday so you can just compare it with gte
Expected output will be
---------------------------
| day | SUM(value) |
| INT(8) | |
---------------------------
| 20191012 | 15.25 |
---------------------------
| 20191011 | 29.13 |
---------------------------
| ... | ... |
---------------------------
J4I: If there are days without values in your dataset, the missing "day-row" is also missing in the output so it could be that there are less than 30 result-rows.
This query will work for any version of MySQL. It creates a temporary numbers table with the numbers from 0-29, then uses that to compute a list of days from today to 29 days earlier. This is then LEFT JOINed to the data table to compute the sum per day, with 0 sums where there is no data for a given day:
SELECT d.day, COALESCE(SUM(value), 0)
FROM (SELECT DATE_FORMAT(CURDATE() -INTERVAL n10.n * 10 + n.n DAY, '%Y%m%d') AS day
FROM (SELECT 0 AS n 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) n
CROSS JOIN (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2) n10) d
LEFT JOIN `table` t ON t.day = d.day
GROUP BY d.day
Demo on dbfiddle

MySQL PHP select rows count in date range

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

Finding Consecutive Streak and Display Count

I have a MySQL table that shows the following:
ID DATE FREQUENCY
-- ---------- ---------
1 2017-08-01 1
2 2017-08-02 1
3 2017-08-03 0
4 2017-08-04 1
5 2017-08-05 1
6 2017-08-06 1
I am trying to get the easiest way to group every time there are consecutive 1's on the frequency column. Then I would like to display them.
Example
2 (There are 2 consecutive 1's)
3 (There are also 3 consecutive 1's)
Thank you
This is a typical gaps-and-island problem.
You can solve it by comparing the overal rank of records to their relative ranks in groups of records having the same frequency. The difference between the ranks gives you the group each record belongs to.
The rest is just filtering and aggregating groups that have a frequency of 1.
Query:
select
min(id) min_id,
max(id) max_id,
min(date) min_date,
max(date) max_date,
count(*) streak_length
from (
select
t.*,
row_number() over(order by date) rn1,
row_number() over(partition by frequency order by date) rn2
from mytable t
) t
where frequency = 1
group by rn1 - rn2
order by min_date
Demo on DB Fiddle with your sample data:
min_id | max_id | min_date | max_date | streak_length
-----: | -----: | :--------- | :--------- | ------------:
1 | 2 | 2017-08-01 | 2017-08-02 | 2
4 | 6 | 2017-08-04 | 2017-08-06 | 3
Note: window function row_number() is available starting MySQL 8.0.

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)

Get Count of each record With Subquery using php mysql

My Db design is :
Tbl_id booked_by date
1 W 2014-02-01
2 P 2014-02-01
3 P 2014-02-01
4 P 2014-02-01
5 W 2014-02-04
6 W 2014-02-04
7 P 2014-02-04
I want to display counting of W , P Where given Date and Grouped by Date and with Using php mysql ..
like
I NEED OUTPUT LIKE THIS:
Tbl_id W P date
1 1 3 2014-02-01
2 2 1 2014-02-04
I need Mysql Query to get output given in above..
You need to use SUM aggregate function for summation and a temp row number for Tbl_id.
select
#rwnm:=#rwnm+1 as Tbl_id,
sum(No_people) as No_people,
sum(Breakfast) as Breakfast,
sum(Lunch) as Lunch,
date
from my_table, ( select #rwnm := 0 ) rownums
group by date
You need the SUM() function, not the COUNT().
SELECT
SUM(No_people),
SUM(Breakfast),
SUM(Lunch),
`date`
FROM yourTable
GROUP BY `date`
I did not include the Tbl_id, because every column you select must be used with an aggregate function or be included in the group by clause. Otherwise it's undetermined which row of the group is selected. Selecting it anyway only works in MySQL, but it does not adhere to the SQL standard. If you want some kind of row number instead either Ravinder's approach or create one on application level (which certainly is easier).
UPDATE:
SELECT
SUM(booked_by = 'W') AS W,
SUM(booked_by = 'P') AS P,
`date`
FROM yourTable
GROUP BY `date`
You still need the SUM() function. booked_by = 'whatever' evaluates to true (1) or false (0).
If you want just the result without slno below query will work fine
SELECT
SUM(No_People) as No_People,
SUM(Breakfast) as Breakfast,
Sum(Lunch) as Lunch,
`date` as date
FROM table_Name
GROUP BY `date`
Output:
No_people Breakfast Lunch date
84 112 160 2014-02-11
116 96 118 2014-02-04
But if you also want serial no. to be displayed then below query will work
SELECT
#slno := #slno + 1 as slno
SUM(No_People) as No_People,
SUM(Breakfast) as Breakfast,
Sum(Lunch) as Lunch,
`date` as date
FROM table_Name, (select #slno := 0 ) sln
GROUP BY `date`
Output:
slno No_people Breakfast Lunch date
1 84 112 160 2014-02-11
2 116 96 118 2014-02-04
Consider the following data set...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,booked_by CHAR(1) NOT NULL
,date DATE NOT NULL
);
INSERT INTO my_table VALUES
(1,'W','2014-02-01'),
(2,'P','2014-02-01'),
(3,'P','2014-02-01'),
(4,'P','2014-02-01'),
(5,'W','2014-02-04'),
(6,'W','2014-02-04'),
(7,'P','2014-02-04');
Here's a pivot query...
SELECT date
, COUNT(CASE WHEN booked_by = 'W' THEN 'foo' END) W
, COUNT(CASE WHEN booked_by = 'P' THEN 'foo' END) P
FROM my_table
GROUP
BY date;
+------------+---+---+
| date | W | P |
+------------+---+---+
| 2014-02-01 | 1 | 3 |
| 2014-02-04 | 2 | 1 |
+------------+---+---+
In my opinion, a better idea (more flexible, more scalable) is simply to return a GROUPED (and, therefore, ordered) result set and handle the rest at in the presentation layer (e.g. a simple PHP loop)...
SELECT date,booked_by,COUNT(*) ttl FROM my_table GROUP BY date,booked_by;
+------------+-----------+-----+
| date | booked_by | ttl |
+------------+-----------+-----+
| 2014-02-01 | P | 3 |
| 2014-02-01 | W | 1 |
| 2014-02-04 | P | 1 |
| 2014-02-04 | W | 2 |
+------------+-----------+-----+

Categories