I have this structure:
id| date_1 | date_2
---------------------
01|2017-01-01|2017-02-22
02|2017-01-02|2017-03-25
03|2017-02-10|2017-03-20
04|2017-03-11|2017-04-10
05|2017-03-15|2017-05-01
06|2017-03-20|2017-05-20
I would need this kind of result:
Month |Count(date_1)|Count(date_2)
---------------------------------
2017-01| 2 | 0
2017-02| 1 | 1
2017-03| 3 | 2
2017-04| 0 | 1
2017-05| 0 | 2
Now, I use this query (it works with only one date):
SELECT CONCAT(YEAR(date_1), '-', DATE_FORMAT(date_1,'%m')) AS month,
COUNT(*) AS items
FROM table
GROUP BY YEAR(date_1), MONTH(date_1)
ORDER BY date_1 DESC
You could union all the date values and then group and count them:
SELECT DATE_FORMAT(d, '%y-%m'), COUNT(*)
FROM (SELECT date_1 AS d FROM mytable
UNION ALL
SELECT date_2 FROM mytable) t
GROUP BY DATE_FORMAT(d, '%y-%m')
ORDER BY d DESC
To get the count of date_1 and date_2 in two different fields, with sub query:
SELECT DATE_FORMAT(temp1.d, '%y-%m'), COALESCE(d1count,0) AS date_1_count, COALESCE(d2count,0)AS date_2_count
FROM (
select date_1 as d from dates group by date_1
union all
select date_2 as d from dates group by date_2
) as temp1
LEFT JOIN (
select date_1, count(*) as d1count
from dates
group by DATE_FORMAT(date_1, '%y-%m')) as temp2
on DATE_FORMAT(temp2.date_1, '%y-%m') = DATE_FORMAT(temp1.d, '%y-%m')
LEFT JOIN (
select date_2, count(*) as d2count
from dates
group by DATE_FORMAT(date_2, '%y-%m')) as temp3
on DATE_FORMAT(temp3.date_2, '%y-%m') = DATE_FORMAT(temp1.d, '%y-%m')
GROUP BY DATE_FORMAT(temp1.d, '%y-%m')
Consider using subqueries behind SELECT
SELECT distinct DATE_FORMAT(t.d, '%y-%m'),
(
SELECT count(*)
FROM your_table as dd
where DATE_FORMAT(dd.date_1, '%y-%m') = DATE_FORMAT(t.d, '%y-%m')
) as count_date_1,
(
SELECT count(*)
FROM your_table as dd
WHERE DATE_FORMAT(dd.date_2, '%y-%m') = DATE_FORMAT(t.d, '%y-%m')
) as count_date_2
FROM
(
SELECT date_1 AS d FROM your_table
UNION ALL
SELECT date_2 as d FROM your_table
) as t
dbfiddle demo
Related
Friends, I am trying to divide two COUNT(*) from MySQL:
I have this query:
SELECT 'Total ', COUNT(*)
FROM root4
WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE()
UNION
SELECT 'Good', COUNT(*)
FROM root4
WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE()
AND testresult ='OK'
The output of this query is looking like this:
________________________
|Total | COUNT(*) |
________________________
|Total| 42 |
|Good | 34 |
_______________________
What I want to achieve is to make another row under "Good" called "FPY" but the value to the dividing of "Good" to "Total" in percentage.
Something like this:
________________________
|Total | COUNT(*) |
________________________
|Total| 42 |
|Good | 34 |
|FPY | 80.95 |
_______________________
I tried to divide them like noob:
SELECT 'Total ', COUNT(*)
FROM root4
WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE()
UNION
SELECT 'Good', COUNT(*)
FROM root4 WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE()
AND testresult ='OK'
UNION
SELECT 'FPY', (COUNT(*)
FROM root4
WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE() /
UNION
SELECT 'Good', COUNT(*)
FROM root4
WHERE str_to_date(DATE, '%d.%m.%Y') = CURDATE()
AND testresult ='OK')
Of course, this is not working...
Note: Colum DATE is varchar that`s why I am using str_to_date.
Look for this:
SELECT COUNT(*) AS Total,
SUM(testresult ='OK') AS Good,
100 * COUNT(*) / SUM(testresult ='OK') AS FPY
FROM root4
WHERE `date` = DATE_FORMAT(CURRENT_DATE, '%d.%m.%Y')
is there any way to print it in two columns as I post in the question? – Azim Feta
WITH cte AS (
SELECT COUNT(*) AS Total,
SUM(testresult ='OK') AS Good
FROM root4
WHERE `date` = DATE_FORMAT(CURRENT_DATE, '%d.%m.%Y')
)
SELECT 'Total' AS indicator, Total AS value FROM cte
UNION ALL
SELECT 'Good', Good FROM cte
UNION ALL
SELECT 'FPY', 100 * Good / Total FROM cte
I think you could be needing a "SubQuery" here.
Something like this:
SELECT
Count(root4.*) AS Total,
root4_1.Good AS Good,
COUNT(root4.*) / root4_1.Good AS FYP
FROM
root4,
(
SELECT
COUNT(*) AS Good
FROM
root4
WHERE
str_to_date(DATE, '%d.%m.%Y') = CURDATE()
AND
testresult ='OK'
)AS root4_1
WHERE
str_to_date(DATE, '%d.%m.%Y') = CURDATE()
Also, see this question, which is similar: How to SELECT based on value of another SELECT
I have Query 1
SELECT COUNT(DISTINCT user_id) total_daily_active_user_group_month FROM (SELECT user_id , MONTHNAME(time) mon , COUNT(*) cnt FROM ACTIVITIES
WHERE MONTH(time) = MONTH(NOW() - INTERVAL 1 MONTH) GROUP by user_id, MONTH(time) ) as x
Returns 18
Query 2
SELECT COUNT(DISTINCT user_id) total_daily_active_user_group_month FROM (SELECT user_id , MONTHNAME(time) mon , COUNT(*) cnt FROM ACTIVITIES
WHERE MONTH(time) = MONTH(NOW() - INTERVAL 1 MONTH) GROUP by user_id, MONTH(time) having cnt=31) as x
Return 6
I want the ratio of query 1 and two. Means
18/6 . I am using MySQL
If you use both queries as CTEs, then it becomes relatively simple:
WITH q1
AS (SELECT Count(DISTINCT user_id) total_daily_active_user_group_month
FROM (SELECT user_id,
Monthname(TIME) mon,
Count(*) cnt
FROM activities
WHERE Month(TIME) = Month(Now() - interval 1 month)
GROUP BY user_id,
Month(TIME))),
q2
AS (SELECT Count(DISTINCT user_id) total_daily_active_user_group_month
FROM (SELECT user_id,
Monthname(TIME) mon,
Count(*) cnt
FROM activities
WHERE Month(TIME) = Month(Now() - interval 1 month)
GROUP BY user_id,
Month(TIME)
HAVING cnt = 31))
SELECT q1.total_daily_active_user_group_month /
q2.total_daily_active_user_group_month
AS result
FROM dual;
You commented that you got an error pointing to the WITH keyword; switch to two subqueries, then; simplified:
select a.value / b.value as result
from (select count(distinct user_id) value
from ... your 1st query goes here
) a,
(select count(distinct user_id) value
from ... your 2nd query goes here
) b;
SELECT CONCAT(MONTH(revenue_date),"/ ", YEAR(revenue_date)) as month_year,
(SELECT COUNT(DISTINCT DATE(delivery_date)) as operating_days
FROM table2 where weekday(delivery_date) <> 5 and
weekday(delivery_date) <> 6 and delivery_date < current_time and
year(delivery_date) > 2015 GROUP BY YEAR(delivery_date), MONTH(delivery_date)),
sum(revenue) as total_revenue,
from table1
where revenue_date < current_time and year(revenue_date) > 2015
group by year(revenue_date), month(revenue_date);
This shows the error "subquery returns more than 1 value". If I don't include group by in the subquery it returns just a total of all of the months but I need it to return it separately for all months.
Try this:
SELECT CONCAT(MONTH(revenue_date),"/ ", YEAR(revenue_date)) as month_year, a.operating_days
sum(revenue) as total_revenue,
from table2 JOIN
(SELECT YEAR(delivery_date) as `year`, MONTH(delivery_date) as `month`, COUNT(DISTINCT DATE(delivery_date)) as operating_days
FROM table2 where weekday(delivery_date) <> 5 and
weekday(delivery_date) <> 6 and delivery_date < current_time and
year(delivery_date) > 2015 GROUP BY YEAR(delivery_date), MONTH(delivery_date)) a
ON year(revenue_date) = a.year AND month(revenue_date) = a.month
where revenue_date < current_time and year(revenue_date) > 2015
group by year(revenue_date), month(revenue_date);
Join with the subquery.
SELECT DATE_FORMAT('%c/%Y', revenue_date) as month_year,
sum(revenue) as total_revenue, operating_days
from table1
JOIN (SELECT YEAR(delivery_date) AS delivery_year, MONTH(delivery_date) AS delivery_month,
COUNT(DISTINCT DATE(delivery_date)) as operating_days
FROM table2
where weekday(delivery_date) <> 5 and
weekday(delivery_date) <> 6 and delivery_date < current_time and
year(delivery_date) > 2015
GROUP BY delivery_year, delivery_month) AS t2
ON YEAR(revenue_date) = delivery_year AND MONTH(revenue_date) = delivery_month
where revenue_date < current_time
group by year(revenue_date), month(revenue_date);
I have two tables:
Table t1:
id | date_click
1 | 2016-02-31 17:17:23
2 | 2016-03-31 12:11:21
3 | 2016-03-31 13:13:23
So from this table I want to get count field Id for each day.
For this I use next query:
SELECT date_format(date_click, '%Y-%m-%d') as date_click_event
, COUNT(id) as count_click
FROM t1
GROUP
BY date_click_event
ORDER
BY date_click_event DESC;
It's work good.
So next table is t2.
id | count | date_sent
1 | 33 | 2016-02-31 11:12:23
2 | 22 | 2016-03-31 14:11:22
3 | 11 | 2016-03-31 13:12:13
To select data by date from this table I use next query:
SELECT date_format(date_sent, '%Y-%m-%d') as date_sent_push
, SUM(count) as count_sent
FROM t2
GROUP
BY date_sent_push
ORDER
BY date_sent_push DESC
LIMIT 100;
It's also work good. So my purpose is merge these two queries into one SELECT that next I can write in php one tables with count of Id by date from table t1 and with count of count field from table t2 by date.
When I try next query:
SELECT date_format(t2.date_sent, '%Y-%m-%d') AS date_sent_push
, SUM(t2.count) as count_sent
, COUNT(t1.id) as count_click
FROM t2
, t1
WHERE date_format(t2.date_sent, '%Y-%m-%d') = date_format(t1.date_click, '%Y-%m-%d')
GROUP
BY date_sent_push
ORDER
BY date_sent_push
DESC
LIMIT 100;
It's not work. What I do wrong?
First you should UNION these results and then group by days and select aggregate fields. Also you can JOIN these queries but it can be a problem if some days miss in one of two tables:
SELECT date_sent_push,
MAX(count_click) as count_click,
MAX(count_sent) as count_sent
FROM
(SELECT date_format(date_click, '%Y-%m-%d') as date_sent_push
, COUNT(id) as count_click
, NULL as count_sent
FROM t1
GROUP BY date_sent_push
UNION ALL
SELECT date_format(date_sent, '%Y-%m-%d') as date_sent_push
, NULL as count_click
, SUM(count) as count_sent
FROM t2
GROUP
BY date_sent_push
) as t3
GROUP BY date_sent_push
SQL fiddle demo
use this code
(SELECT date_format(date_sent, '%Y-%m-%d') as date_sent_push, SUM(count) as count_sent FROM t2 GROUP BY date_sent_push ORDER BY date_sent_push DESC LIMIT 100)
UNION
(SELECT date_format(t2.date_sent, '%Y-%m-%d') AS date_sent_push, SUM(t2.count) as count_sent, COUNT(t1.id) as count_click FROM t2, t1 WHERE date_format(t2.date_sent, '%Y-%m-%d')=date_format(t1.date_click, '%Y-%m-%d') GROUP BY date_sent_push ORDER BY date_sent_push DESC LIMIT 100)
I am trying to get the total sum of a column and the sum of the same column between 2 dates in one query. is this possible?
My table looks like this:
uid|amount|date
The two queries i am trying to make one of:
SELECT sum(amount) as `keys` FROM tbl_keys WHERE uid = 1
SELECT sum(amount) as `keys` FROM tbl_keys WHERE uid = 1 AND YEAR(`date`) = YEAR(CURRENT_DATE)
AND MONTH(`date`) = MONTH(CURRENT_DATE)
You could use a UNION query:
SELECT 'All' AS cnt, sum(amount) as `keys` FROM tbl_keys WHERE uid = 1
UNION ALL
SELECT 'Current_month' AS cnt, sum(amount) as `keys`
FROM tbl_keys
WHERE
uid = 1
AND `date`<= last_day(current_date)
`date`>= current_date - interval (day(current_date)-1) day
(I prefer to use >= and <= on the date column, as it can make use of an index if present, while functions like MONTH() or YEAR() cannot, also I assume that date is a date columnd and that it doesn't contain time informations).
If you want the result in one row, you could use an inline query:
SELECT
(SELECT sum(amount) as `keys` FROM tbl_keys WHERE uid = 1) AS total,
(SELECT sum(amount) as `keys`
FROM tbl_keys
WHERE
uid = 1
AND `date`<= last_day(current_date)
`date`>= current_date - interval (day(current_date)-1) day
) AS current_month
Something like this:
SELECT sum(amount) as `keys`,
(
SELECT sum(t.amount)
FROM tbl_keys as t
WHERE t.uid = tbl_keys.uid AND YEAR(t.`date`) = YEAR(CURRENT_DATE)
AND MONTH(t.`date`) = MONTH(CURRENT_DATE)
) as `keys2`
FROM tbl_keys
WHERE uid = 1
SELECT sum(amount) AS `keys`
FROM (
SELECT amount FROM tbl_keys
UNION ALL
SELECT amount FROM tbl_keys
WHERE uid = 1
AND YEAR(`date`) = YEAR(CURRENT_DATE)
AND MONTH(`date`) = MONTH(CURRENT_DATE)
) AS new_table;
Using a UNION clause, you will get the desired output you want.
Use CASE to count only the amount for the specified date:
SELECT SUM(amount) AS `keys`,
SUM(CASE WHEN YEAR(`date`) = YEAR(CURRENT_DATE)
AND MONTH(`date`) = MONTH(CURRENT_DATE) THEN amount ELSE 0 END) AS 'keys2'
FROM tbl_keys
WHERE uid = 1
;
My guess is that this will run more efficient than a solution using UNION SELECT.