select user_id as sponsor_id,sum(points),created_at
from points_history
where created_at between '2014/08/12' and '2015/08/12' and transaction_type="debit"
group by user_id,DATE_FORMAT(created_at,"%d %M %Y")
order by DATE_FORMAT(created_at,"%d %M %Y"),sum(points) desc
sponsor_id sum(points) created_at
1 30 2014-12-08 10:54:59
2 25 2014-12-09 05:43:11
3 20 2014-12-09 06:58:40
1 5 2014-12-09 05:56:12
1 34 2014-08-23 10:42:32
here I want to calculate rank of particular sponsor using sponsor_id on daily basis .. I want to build a query that can return me something like as displayed below:
sponsor_id rank created_at
1 1 2014-12-08 10:54:59
1 3 2014-12-09 05:56:12
1 1 2014-08-23 10:42:32
I think I can use sub query like
select *
from (select user_id as sponsor_id,sum(points),created_at
from points_history
where created_at between '2014/08/12' and '2015/08/12' and transaction_type="debit"
group by user_id,DATE_FORMAT(created_at,"%d %M %Y")
order by DATE_FORMAT(created_at,"%d %M %Y"),sum(points) desc
) as t
where t.sponsor_id = 1
but how to calulate rank here.
Try this:
SELECT sponsor_id, points, created_at,
IF(#dte=#dte:=DATE(created_at), #rank:=#rank+1, #rank:=1) AS rank
FROM (SELECT user_id AS sponsor_id, SUM(points) points, created_at
FROM points_history
WHERE created_at BETWEEN '2014-08-12' AND '2015-08-12' AND
transaction_type = "debit"
GROUP BY user_id, DATE_FORMAT(created_at,"%d %M %Y")
ORDER BY DATE(created_at), SUM(points) DESC
) AS A, (SELECT #rank:=0, #dte:='') AS B
ORDER BY DATE(created_at), points DESC;
Related
i have a mysql query as
SELECT date,shortcode,SUM(count) as myCount
FROM mytable
WHERE smsc='123'
AND username NOT REGEXP '[A-Za-z]+'
AND DATE(date) >= CURDATE() - INTERVAL 7 DAY
GROUP BY shortcode,date
ORDER BY date ASC
Which gives the result as following which is perfectly fine
date
shortcode
myCount
2021-02-18
123
7
2021-02-18
231
15
2021-02-19
783
117
2021-02-19
894
115
2021-02-20
009
70
2021-02-20
565
15
now what i want to do is get max value of maxcount from each day and corresponding shortcode so what i did is
Select date,Max(myCount) as maxim,shortcode
from ( SELECT date,shortcode,SUM(count) as myCount
FROM mytable
WHERE smsc='123'
AND username NOT REGEXP '[A-Za-z]+'
AND DATE(date) >= CURDATE() - INTERVAL 7 DAY
GROUP BY shortcode,date
ORDER BY date ASC ) as a
GROUP BY a.date;
which is not giving me the right result
my desired result is
date | shortcode | maxim
2021-02-18 | 231 |15
2021-02-19 | 783 |117
2020-02-20 | 009 |70
You can use common table expression and row_number() to achieve your desired result:
with cte as (
select date,shortcode,mycount,row_number()over(partition by date order by mycount desc) rn from (SELECT date,shortcode,SUM(count) as myCount
FROM mytable
WHERE smsc='123'
AND username NOT REGEXP '[A-Za-z]+'
AND DATE(date) >= CURDATE() - INTERVAL 7 DAY
GROUP BY shortcode,date )t)
select date,shortcode,mycount from cte where rn=1
This query will generate a sequence for each date orderring by mycount in descendent order. So always the first row for each date will contain the max mycount.
If you can use a variable, the query is:
SET #x='';
SELECT
#x:=date,shortcode,myCount FROM (
SELECT date,shortcode,SUM(count) as myCount
FROM mytable
WHERE smsc='123'
AND username NOT REGEXP '[A-Za-z]+'
AND DATE(date) >= CURDATE() - INTERVAL 7 DAY
GROUP BY shortcode,date
ORDER BY date ASC,myCount DESC
) a
WHERE #x<>date
;
Fiddle
I have table orders:
id
login_name
success
order_date
1
login1
0
2021-01-05
2
login2
0
2021-01-06
3
login3
0
2021-01-08
4
login1
1
2021-01-04
5
login2
0
2021-01-01
I need to select id, login_name with success=0 for which exist another order with order_date older or younger than 60 days.
The result should be:
1 - login1, 2 - login2, 5 - login2
I have this, but I think that is not a right way:
SELECT id, login_name, COUNT(*)
FROM orders
WHERE success=0
GROUP BY login_name
HAVING COUNT(*) > 1
You can use the EXISTS as follows:
SELECT id, login_name, COUNT(*)
FROM orders r
WHERE success=0
and exists
(select 1 from orders rr
where rr.login = r.login
and abs(datediff(rr.order_date, r.order_date)) <= 60
and rr.id <> r.id
)
If you want orders that appear within 60 days of each other, you can use lag() and lead():
select o.*
from (select o.*,
lag(order_date) over (partition by login_name order by order_date) as prev_order_date,
lead(order_date) over (partition by login_name order by order_date) as lead_order_date
from orders o
) o
where prev_order_date > dateadd(day, -60, order_date) or
next_order_date < dateadd(day, 60, order_date);
I have a table with the following schema:
+-------------------------------------------------------+
| table_counter |
+----+---------------------+------------+---------------+
| id | timestamp | entry_type | country |
+----+---------------------+------------+---------------+
+----+---------------------+------------+---------------+
| 10 | 2017-05-01 12:00:00 | click | Germany |
+----+---------------------+------------+---------------+
| 11 | 2017-05-01 12:00:00 | view | Austria |
+----+---------------------+------------+---------------+
| 12 | 2017-05-01 12:00:00 | click | UK |
+----+---------------------+------------+---------------+
| 13 | 2017-05-01 12:00:00 | view | USA |
+----+---------------------+------------+---------------+
I need to return the following result: Select the sum of views and clicks of the top 5 countries by sum of views in the past 30 days.
I know how to count the records all right, but how do I define the constrains? How do I return all entries from five countries with the highest number of views?
Limiting the result to the last 30 days is trivial, but I'm pretty much stuck at the beginning.
Using order by and limit keywords,
SELECT SUM(IF(entry_type = "view", 1, 0)) as view_count FROM t3 GROUP BY country, entry_type ORDER BY view_count DESC LIMIT 5
--EDIT
As per the requirement stated in the comments, here's the updated query:
SELECT SUM(view_click_count) as all_total FROM (SELECT country, SUM(IF(entry_type = "view", 1, 0)) as view_count, SUM(IF(entry_type = "click", 1, 0)) as click_count, count(entry_type) as view_click_count FROM t3 GROUP BY country ORDER BY view_count DESC LIMIT 5) t2
all_total gives the total count as needed, for top 5 countries.
You can do it this way:
select
tc.country,
count(case entry_type when 'click' then 1 else null end) clicks,
count(case entry_type when 'view' then 1 else null end) views
from table_counter tc
inner join (
select top 5 country from [dbo].[table_counter]
where entry_type = 'view'
and timestamp >= DATEADD(DAY, -30, GETDATE())
group by country
order by count(entry_type) desc
) t on t.country = tc.country
where timestamp >= DATEADD(DAY, -30, GETDATE())
group by tc.country
order by views desc
This is for SQL Server. A few tweaks might be needed for MySQL (i.e. 'Limit' instead of 'TOP')
You can get top 5 countries by views with the following query, e.g.:
SELECT country, count(*) as 'views'
FROM table
WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
AND entry_type = 'view'
GROUP BY country
ORDER BY count(*) DESC
LIMIT 5
Now, to select clicks, you can add another query in SELECT , e.g.:
SELECT t.country, COUNT(*) as 'views',
(SELECT COUNT(*)
FROM `table`
WHERE country = t.country
AND entry_type = 'click'
AND timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
) as 'clicks'
FROM `table` t
WHERE t.timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
AND t.entry_type = 'view'
GROUP BY t.country
ORDER BY count(*) DESC
LIMIT 5
Here's the SQL Fiddle.
Update
To get the SUM of views and clicks, wrap the above query into another SELECT, e.g.:
SELECT country, views + clicks
FROM(
SELECT t.country, COUNT(*) as 'views',
(SELECT COUNT(*)
FROM `table`
WHERE country = t.country
AND entry_type = 'click'
AND timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
) as 'clicks'
FROM `table` t
WHERE t.timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()
AND t.entry_type = 'view'
GROUP BY t.country
ORDER BY count(*) DESC
LIMIT 5
) b;
Here's the updated SQL Fiddle.
I have the following table:
user_id post_streak streak_date streak first_name club_id
-------- ----------- ------------ --------- ----------- --------
18941684 1 2015-05-05 15:36:18 3 user 1000
I want to change streak to 0 if it has been longer then 12 days.
current query:
select
first_name, streak, user_id from myTable
where
club_id = 1000
and
post_streak = 1
and
streak_date between date_sub(now(),INTERVAL 12 DAY) and now()
order by streak desc;
Which doesn't show results older then 12 days. I want to show all results but change "streak" to 0 if it has been longer the 12 days.
What is the best way to go about this?
UPDATE table
SET (streak)
VALUES (0)
WHERE streak_date < DATEADD(DAY, -12, NOW() );
SELECT first_name, streak, user_id from myTable
WHERE
club_id = 1000
AND
post_streak = 1
ORDER BY streak DESC;
First query will set all streak values to 0 for records that have streak_date of more than 12 days ago
Second query will get a list of all your records that have a club_id of 1000 and a post_streak of 1
Put the condition in the select, rather than the where:
select first_name,
(case when streak_date between date_sub(now(), INTERVAL 12 DAY) and now()
then streak
else 0
end) as streak,
user_id from myTable
where club_id = 1000
order by streak desc;
I'm not sure if the post_streak condition is needed in the where clause.
http://sqlfiddle.com/#!9/d8bbd/6
select
user_id,
first_name,
streak_date,
IF(streak_date between date_sub(now(),INTERVAL 12 DAY) and now(),streak,0)
from myTable
where
club_id = 1000
and
post_streak = 1
order by streak desc;
I have 2 different tables, users and votes. I would like to get a query to count total users and total votes (not sum) by date.
users
id | created_at
votes
id | created_at
I want the result to look like this:
date | total users | total votes
2012-06-01 | 50 | 90
2012-06-01 | 23 | 0*
2012-06-01 | 80 | 12
*It should take into account that on some days no votes were made
I know how to make the 2 separate queries
SELECT DATE(created_at), count(id)
FROM vote
GROUP by DATE(created_at)
ORDER by DATE(created_at) DESC
but I don't know how to join them.
Try this:
SELECT
DATE(created_at),
SUM(CASE WHEN `Type` = 'Votes' THEN 1 ELSE 0 END) AS 'TotalVotes',
SUM(CASE WHEN `Type` = 'Users' THEN 1 ELSE 0 END) AS 'TotalUsers'
FROM
(
SELECT created_at, 'Votes' `Type` FROM vote
UNION ALL
SELECT created_at, 'Users' FROM Users
) t
GROUP by DATE(created_at)
ORDER by DATE(created_at) DESC
Try this:
SELECT created_at, SUM(votes) AS 'TotalVotes', SUM(users) AS 'TotalUsers'
FROM(SELECT DATE(created_at) created_at, COUNT(ID) votes, 0 users
FROM votes GROUP BY DATE(created_at)
UNION
SELECT DATE(created_at) created_at, 0 votes, COUNT(ID) users
FROM Users GROUP BY DATE(created_at)) t
GROUP BY created_at
ORDER BY created_at DESC
SELECT DATE(created_at),SUM(usercolumnname) as totalusers,
SUM(//votescolumnname) as totalvotes from users u,votes v
where u.date=v.date
GROUP BY u.DATE(created_at)
ORDER BY u.DATE(created_at) DESC