I have a table "UserLogins" and when the user login into the system I will drop a record in the "UserLogins" table.
Jan 10th (Users : 1,2,3,4) // four records with Ids 1,2,3,4
Jan 20th (1,2,3,4,5,6) // six records with Ids 1,2,3,4,5,6
Jan 30th (1,2)
Feb 10th (1,7)
Feb 20th (2,6,8)
Feb 25th (1,2,3,5)
Mar 10th (3,4)
Mar 20th (4,5,9)
Mar 30th (8,10,11)
Apr 10th (10,12)
Apr 20th (1,2,3,6,13, 14, 15)
Apr 30th (11,12,16)
When I write the group by my results as follows
Jan - 6
Feb - 7
Mar - 7
Apr - 11
But I need an out put like as follows
Upto Jan - 6 //count of distinct users upto Jan
Upto Feb - 8 //count of distinct users upto Feb
Upto Mar - 11 //count of distinct users upto Mar
Upto Apr - 16 //count of distinct users upto Apr
Your first count could simply be like this:
SELECT
DATE_FORMAT(login_date, '%Y-%b') AS year_month,
COUNT(DISTINCT user_id)
FROM
UserLogins
GROUP BY
DATE_FORMAT(login_date, '%Y-%b')
while to count all users up to a given mount, I would use a Join:
SELECT
DATE_FORMAT(last_day, '%Y-%b') AS year_month,
COUNT(DISTINCT user_id)
FROM
(SELECT DISTINCT LAST_DAY(login_date) as last_day
FROM UserLogins) d
INNER JOIN
UserLogins ON UserLogins.login_date<=last_day
GROUP BY
DATE_FORMAT(last_day, '%Y-%b')
on the subquery d I will return all last days of every month that has a record on the UserLogins table, then I will join all userlogin that logged up to the end of the month, and then I will do the count.
Related
I am trying to display records using group by name but when the sdate is available.
my table :
Example
Hotel Tampa is available on jan 1, jan 4,jan 6
then I want to show like this
name
available date
tampa
jan 1 , jan 2 , jan 6
tabcd
jan 3 , jan 9 , jan 12
SELECT name, GROUP_CONCAT(sdate) as gr_date FROM table_name GROUP BY name
So, I have a mysql table with user id(id) and date of transaction(dot) that looks like:
id dot
-------------------------------
101 2015-06-12 12:18:42 UTC
102 2015-06-12 12:18:40 UTC
103 2015-06-12 12:18:42 UTC
101 2015-07-12 12:18:42 UTC
and so on.
(Output for this data should be:
Year Month Num of users
-----------------------------
2015 06 0
2015 07 2
)
It logs all the transactions that are made. For each month m, I want to find out the count of users by month and year who transacted in m-1 month but not in m month. The results need to be grouped by year and month. Ideally, table should look like (http://sqlfiddle.com/#!9/b80f49/1)
Year Month Num of users
-----------------------------
2015 05 0
2015 06 2
2015 07 1
2015 08 4
Now for a single month(E.g. 05/2015), I can hardcode:
SELECT "2015" AS Year,"05" AS Month, "COUNT(DISTINCT id) FROM table WHERE
MONTH(dot)=4 AND YEAR(dot)=2015
AND id NOT IN
(SELECT id FROM table WHERE MONTH(dot)=5 AND YEAR(dot)=2015)
To group the count of users using GROUP BY, the query would look like:
SELECT YEAR(dot) as Year,MONTH(dot),COUNT(DISTINCT id) as Month FROM table
WHERE id NOT IN(SELECT id FROM table
WHERE DATEDIFF(dot_parent,dot_this_table)<30 AND DATEDIFF(dot_parent,dot_this_table)>=0)
Here dot_parent is the dot of the parent query and dot_this_table is the dot of the subquery. Now the problem here is that I can't pass the dot_parent inside the subquery. Is there a way to do that or frame the query in another way such that its logical structure remains similar, since I would have to make similar queries for multiple date ranges.
You must query the same table thrice: once for the months to show, once to find the users in the previous months, once for user matches in the months in question. You'd select distinct users per month, as you are not interested in whether a user had more than one transaction in a month or not.
Here is the complete query:
select
this_month.year,
this_month.month,
count(prev_month_users.user) - count(this_month_users.user) as users
from
(
select distinct year(timing) as year, month(timing) as month
from transactions
) this_month
left join
(
select distinct
year(timing) as year, month(timing) as month, id as user,
year(date_add(timing, interval 1 month)) as next_month_year,
month(date_add(timing, interval 1 month)) as next_month_month
from transactions
) prev_month_users
on prev_month_users.next_month_year = this_month.year
and prev_month_users.next_month_month = this_month.month
left join
(
select distinct year(timing) as year, month(timing) as month, id as user
from transactions
) this_month_users
on this_month_users.user = prev_month_users.user
and this_month_users.year = prev_month_users.next_month_year
and this_month_users.month = prev_month_users.next_month_month
group by this_month.year, this_month.month;
Result:
year month users
2015 5 0
2015 6 2
2015 7 1
2015 8 3
Note that I show three users for August (users 101, 102, 104). User 101 had two transactions in July, but it is still three users who had transactions in July but not in August.
Here is your SQL fiddle back: http://sqlfiddle.com/#!9/b80f49/13
I have employees table with date_of_join field
and I have employee_leaves table with the following fields:
employee_id
leave_from
leave_to
total_days
the employee joined on 15 Feb 2011
I want to have a query showing the cound of leaves for every employee years based on his date_of_join
for example, if the employee joined on 15 Feb 2011 then the result will be like this:
Feb 2011 to feb 2012 ---- totals days: 21
Feb 2012 to feb 2013 ---- totals days: 26
Feb 2013 to feb 2014 ---- totals days: 8
where Feb to feb is the employee year so it's from 15 Feb to 14 Feb every year
can anyone help please?
Not having your data it is difficult to test this but I came up with the following based on your description:
SELECT employees.employee_id, DATE_ADD(employees.date_of_join, INTERVAL yrs.years) frm
,DATE_ADD(employees.date_of_join, INTERVAL yrs.years + 1) too,
SUM(employee_leaves.total_days)
FROM employee_leaves
INNER JOIN (SELECT 0 years UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) yrs
ON 1=1
INNER JOIN employees ON employee_leaves.employee_id = employees.employee_id
AND employee_leaves.leave_from BETWEEN DATE_ADD(employees.date_of_join, INTERVAL yrs.years) AND DATE_ADD(employees.date_of_join, INTERVAL yrs.years + 1)
GROUP BY employees.employee_id, DATE_ADD(employees.date_of_join, INTERVAL yrs.years)
;
Probably needs some fiddling, hope this helps.
I am driving nuts to get what it was supposed to be a simple query done. I have the following table:
Daily Check-In Table: tbl_checkin (uniqueid, userid, clock)
Sample data:
1 1 7/25/2014 12:00:00 AM
2 1 7/25/2014 2:37:05 PM
3 2 7/25/2014 3:22:29 PM
Calendar Table: calendar (datefield)
Sample data contains dates from 2012 to 2050 (i.e. 1/1/2012 12:00:00 AM, etc..)
I am looking to get this result:
Date: Count:
Jul 21 0
Jul 22 0
Jul 23 0
Jul 24 0
Jul 25 3
Jul 26 0
Jul 27 0
Jul 28 0
My query specifies a date range. In the above sample, I specified 1 week but I could specified any date range. The closest I got with the query is this:
SELECT
date_format(calendar.datefield, '%b %e') AS clockdate,
COUNT(*) AS total
FROM tbl_checkin RIGHT JOIN calendar ON (DATE(tbl_checkin.clock) = calendar.datefield)
WHERE (calendar.datefield BETWEEN (SELECT MIN(DATE('2014-07-21')) FROM tbl_checkin)
AND (SELECT MAX(DATE('2014-07-28')) FROM tbl_checkin))
GROUP BY clockdate;
The result I get is this:
Date: Count:
Jul 21 1
Jul 22 1
Jul 23 1
Jul 24 1
Jul 25 3
Jul 26 1
Jul 27 1
Jul 28 1
For some reason I get 1 on the dates I have nothing. A user could have multiple entries in a single day. Does anyone see what I am doing wrong? Thanks a lot.
When count(*) is used, rows where tbl_checkin.clock is null is also counted as 1 (because of the right join). We just need to replace count(*) with count(tbl_checkin.clock):
SELECT
date_format(calendar.datefield, '%b %e') AS clockdate,
COUNT(tbl_checkin.clock) AS total
FROM tbl_checkin
RIGHT JOIN calendar ON DATE(tbl_checkin.clock) = calendar.datefield
WHERE calendar.datefield BETWEEN '2014-07-21' AND '2014-07-28'
GROUP BY clockdate;
there any ways to merge row values. suppose emp Name is same for different month.
for e.g
emp Name Jan Feb Mar
a 1
a 5
a 9
I want result Like:-
emp Name Jan Feb Mar
a 1 5 9
Try MAX:
SELECT `emp Name`,MAX(Jan) as Jan,MAX(Feb) as Feb, MAX(Mar) as Mar
FROM TableName
GROUP BY `emp Name`
Learn more about the aggregate function MAX() here.