How to fetch multiple duplicate value count in sql - php

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)

Related

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

Get total of amount based on date

PaymentHistory Table
==========================
UserId | Amount | Date
==========================
1 | 300 | 2014-06-26
3 | 300 | 2014-06-26
2 | 200 | 2014-06-26
1 | 400 | 2014-06-22
1 | 100 | 2014-06-21
display two columns first is sum of amount as Named "currentEarning" which has same date of today and second is sum of amount as Named "oldEarning" based on previous date of today. (for particular userId) see output:
output
=====================================
UserId | currentEarning | oldEarning |
=====================================
1 | 300 | 500
You can do that with one query:
SELECT
SUM(IF(`Date` = CURRENT_DATE, AMOUNT, 0)) AS currentEarning,
SUM(IF(`Date` < CURRENT_DATE, AMOUNT, 0)) AS oldEarning
FROM PaymentHistory
GROUP BY `UserId`
Way more efficient than subqueries or two separate queries.
Get current amount:
SELECT UserId, SUM(Amount) as currentEarning, Date FROM PaymentHistory WHERE UserId = '1' AND DATE(Date) = CURDATE()
Get old amount:
SELECT UserId, SUM(Amount) as oldEarning, Date FROM PaymentHistory WHERE UserId = '1' AND DATE(Date) != CURDATE()
This should work
SELECT `UserId`,
(SELECT SUM(`Amount`) FROM `PaymentHistory` WHERE `UserID` = t1.`UserId` AND `Date` = t1.`Date`) AS `currentEarning`,
(SELECT SUM(`Amount`) FROM `PaymentHistory` WHERE `UserID` = t1.`UserId` AND `Date` < t1.`Date`) AS `oldEarning`
FROM PaymentHistory AS t1
WHERE t1.`Date` = CURRENT_DATE
GROUP BY t1.`UserId`
HAVING `oldEarning` IS NOT NULL

Mysql query group by taking wrong time stamp

I have a query that when executed gives me the result like this
speciaid | title | date
one | xxx | 2013-10-03 02:13:54
one | xxx | 2013-10-03 03:13:54
two | yyy | 2013-10-02 02:13:54
Now if I add GROUP BY specialid, it gets grouped but the date i get is the old date and not the new date for the 'date' column like this
speciaid | title | date
one | xxx | 2013-10-03 02:13:54 // old date selected for entry one
two | yyy | 2013-10-02 02:13:54
and I want it like this
speciaid | title | date
one | xxx | 2013-10-03 03:13:54 // new date for entry one needed
two | yyy | 2013-10-02 02:13:54
I have tried many group by's - I get the same result. I would appreciate it very much if someone help with the group by statement for query.
You're looking for a greatest-n-per-group solution.
Usually solved this way (assuming your result is the table, due to the lack of information in the question).
Option 1:
SELECT * FROM t JOIN (
SELECT title, max(`date`) `date` FROM t
GROUP BY title
) s ON t.title = s.title AND t.`date` = s.`date`
Option 2:
SELECT t1.* FROM t t1
LEFT JOIN t t2
ON t1.title = t2.title AND t1.`date` < t2.`date`
WHERE t2.`date` IS NULL
Working fiddle: http://sqlfiddle.com/#!2/76f2d3/1
If you want to get first/last date from grouped column you need to use max() or min() grouped function.
SELECT speciaid, title, MAX(`date`) FROM table GROUP BY title;
select speciaid, title , date
from
(select * from table_name order by date desc) d
group by title

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')

MySQL - SELECT columns according to their values

I have an events table in my database, and each event can
have up to 5 different dates.
Date1 in the table is always before date2, date2 before date3 etc.
Given 2 dates in the search form, I'm trying to find the events between them.
My table is designed as follows:
id | name | date1 | date2 | date3 | date4 | date5
1 | test1 | 2013-05-24| 2013-05-25 | 0000-00-00| 0000-00-00| 0000-00-00
2 | test2 | 2013-06-01| 2013-06-08 | 2013-06-15| 2013-06-23| 2013-06-30
3 | test3 | 2013-03-15| 0000-00-00 | 0000-00-00| 0000-00-00| 0000-00-00
$datefrom , $dateto are the two variables from the search form.
Now the $datefrom for example, will always search in date1 of the table.
But $dateto has to search in date5, and if it is null to date4 and so on.
The best query I came up with so far is this:
SELECT * FROM events
WHERE
IF(date1 != '0000-00-00', IF(date1>='2012-12-19', 1, 0),0) = 1
AND CASE
WHEN date5!='0000-00-00' THEN IF(date5<='2012-12-31', 1, 0)
WHEN date4!='0000-00-00' THEN IF(date4<='2012-12-31', 1, 0)
WHEN date3!='0000-00-00' THEN IF(date3<='2012-12-31', 1, 0)
WHEN date2!='0000-00-00' THEN IF(date2<='2012-12-31', 1, 0)
END
But it is not working very well, for example this query returns rows with its oldest date being in 2013. I don't know if CASE is the right approach to begin with.
Any ideas?? Thanks for your time!
you can use it so simple with GREATEST
SELECT name , date1 date_start, GREATEST(date2,date3,date4,date5) date_end
FROM events
and will output like that
NAME DATE_START DATE_END
jack 2013-05-24 2013-05-25
peter 2013-06-01 2013-06-30
here THE DEMO SQLFIDDLE
Try this:
SELECT
id,
name
FROM
(
SELECT
id,
name,
MIN(EventDate) AS "FromDate",
MAX(EventDate) AS "ToDate"
FROM
(
SELECT id, name, date1 As "EventDate" FROM events
UNION ALL
SELECT id, name, date2 FROM events
UNION ALL
SELECT id, name, date3 FROM events
UNION ALL
SELECT id, name, date4 FROM events
UNION ALL
SELECT id, name, date5 FROM events
) t
GROUP BY id, name
) t
WHERE FromDate > #fromdate
AND ToDate < #todate;
SQL Fiddle Demo
However, if you want to get the data in the same way as it is in the events table, you can do this:
SELECT
e.*
FROM
(
SELECT
id,
name,
MIN(EventDate) AS "FromDate",
MAX(EventDate) AS "ToDate"
FROM
(
SELECT id, name, date1 As "EventDate" FROM events
UNION ALL
SELECT id, name, date2 FROM events
UNION ALL
SELECT id, name, date3 FROM events
UNION ALL
SELECT id, name, date4 FROM events
UNION ALL
SELECT id, name, date5 FROM events
) t
GROUP BY id, name
) t
INNER JOIN events e ON t.id = e.id
WHERE t.FromDate > #fromdate
AND t.ToDate < #todate;
For instance, for #fromdate = '2012-05-01' and #todate = '2012-06-15', this will give you:
| ID | NAME | DATE1 | DATE2 | DATE3 | DATE4 | DATE5 |
---------------------------------------------------------------------------------------------------
| 1 | test1 | May, 24 2013 00:00:00+0000 | May, 25 2013 00:00:00+0000 | (null) | (null) | (null) |

Categories