I am trying to select Maximum Date and Second Max Date but can't get success.
This is table data.
ID Country DATE
1 Canada 2016-05-26
2 Canada 2016-05-25
3 Canada 2016-05-24
4 USA 2016-04-02
5 USA 2016-04-01
6 USA 2016-03-20
Expecting Output
Country Max_Date 2nd_Date
Canada 2016-05-26 2016-05-25
USA 2016-04-02 2016-04-01
What I have done so for:
Get Max Date using this query.
select Country, MAX(Date) from tbl GROUP BY (Country);
For Second Max date but failed to get result:
SELECT Country, MAX(date) FROM tbl WHERE Date NOT IN
( select MAX(FROM) from tbl GROUP BY (Country)) GROUP BY (Country)
What should I try to get expected output. Thanks
Or you could try this
SELECT s.Country, Max(s.Date) Max_Date,
(SELECT t.Date
FROM tbl t
Where s.Country=t.Country
ORDER BY Date DESC
LIMIT 1,1) 2nd_Date
FROM tbl s
GROUP BY COUNTRY;
The LIMIT clause is zero based, so using parameters 1,1 skips the first (ie max) value & returns just one value (2nd max).
NOTE - if the max date is duplicated the query will return Max_Date & 2nd_Date as the same value - if that is not what you want, then you can add DISTINCT to the inner query.
No need for nested queries to solve this:
SELECT t1.country, max(t1.date), max(t2.date)
FROM tbl t1
JOIN tbl t2 ON t1.country = t2.country AND t2.date < t1.date
GROUP BY t1.country;
This can be a pain. Here is one method:
select t.country, maxdate, max(t.date) as secondate
from tbl t left join
(select country, max(date) as maxdate
from tbl
group by country
) c
on t.country = c.country and t.date < c.maxdate
group by t.country;
Try this one
Select Country, MAX(Date) As Date From tbl GROUP BY Country Order By Date Desc Limit 2;
Related
Let's say the table looks like this:
user id
date
Amount
123
2022/11/01
5
456
2022/11/02
6
789
2022/11/03
8
123
2022/11/02
9
456
2022/11/04
6
789
2022/11/05
8
I want to calculate the sum of the very last transaction (only one for each user) for A & B FYI I'm using redash and I'm a beginner not sure what other info would you need, I tried MAX but was not sure how to apply it on more than one specific user.
Get the sum of Amount where user is A or B and date is the most recent date for each user
SELECT SUM(AMOUNT) AS total
FROM (
SELECT AMOUNT, ROW_NUMBER() OVER (PARTITION BY USERID ORDER BY DATE DESC) AS RN
FROM tableyoudidnotname
WHERE userid in ('A','B')
) X
WHERE X.RN = 1
You can try this, where we first calculate the maximum date by user in a common-table expression, then join that result-set to the table to sum the associated values.
WITH dat
AS
(
SELECT user_id, MAX(date) AS max_date
FROM credit.card
WHERE user_id IN ('A','B','ETC')
GROUP BY user_id
)
SELECT SUM(value) AS sum_on_max_dates
FROM credit.card t
INNER JOIN dat d ON t.user_id = d.user_id AND t.date = m.max_date;
You can try this, Used join with the subquery I mention below.
SELECT
SUM(t1.amount) AS count
FROM
transaction t1
JOIN
(SELECT
user_id, MAX(date) AS max_date
FROM
transaction
WHERE
user_id IN ('A', 'B')
GROUP BY user_id) t2 ON t1.user_id = t2.user_id
AND t2.max_date = t1.date;
i have a DB with this structure
id, UserID, price, Date
,1, 10.00, 2000-01-01
,1, 25.00 ,2022-02-01
,2, 12.00 ,2000-01-05
,2, 13.00 ,2001-01-05
,2, 24.00 ,2022-01-01
,3, 23.00 ,2022-01-01
i want to show the price for each user based on newest date.
So just 1 row per UserID (latest date)
if we query above table. results need to be like this:
,1, 25.00 ,2022-02-01
,2, 24.00 ,2022-01-01
,3, 23.00 ,2022-01-01
i have tried those 2 commands but they are not working
SELECT UserID,price,Datee FROM (SELECT UserID,price,Datee FROM tbl
ORDER BY UserID ASC,datee DESC) as tb_temp GROUP BY UserID
also this
SELECT UserID,price,max(Datee) FROM tbl Group by UserID ORDER BY UserID ASC,datee DESC
this command show latest date but price is not based on that
so i need something like ORDER BY datee then group by userID or LIMIT 1 per userID
If you're on MySQL 8, the most common way to achieve this is with a window function:
select userid, price, date
from (select *
, row_number() over (partition by userid
order by date desc) as row_priority
from tbl
) subq
where subq.row_priority = 1
Here's a working demo on dbfiddle
You could use a window function to good effect as MarcinJ has done--another approach would be to use a correlated subquery:
SELECT
S1.UserID,
S1.price,
S1.Date
FROM
SampleDetails S1
WHERE
S1.Date = (SELECT MAX(S2.Date) FROM SampleDetails S2 WHERE S2.UserID = S1.UserID GROUP BY S2.UserID);
You can try it out on DB Fiddle.
You could try this, it's not the most efficient because it uses a sub-query:
SELECT t.UserID, t.price, t.Datee
FROM tbl t
JOIN tbl on t.id = (SELECT id FROM tbl WHERE UserID = t.UserID ORDER BY Datee DESC LIMIT 1)
GROUP BY UserID
The idea is to join the table to itself by finding the latest row for the user id.
I made this sql fiddle to test it: http://sqlfiddle.com/#!9/63d495/2
i want to count 2 tables from diferent table, im select the date then i group it.
here what i try
SELECT
(SELECT date(date), COUNT(sh_sh) FROM sh_url GROUP BY date(date)) AS URLs,
(SELECT date(date), COUNT(ip) FROM tracking GROUP BY date(date)) AS IP
FROM dual
but i get error
1241 - Operand should contain 1 column(s)
is that posible to do it in one command?
the output should be like this
date(url) count(sh_sh) date(ip) count(ip)
--------- ------------ ---------- ----------
2018-04-25 123 2018-04-25 123123
2018-04-26 456 2018-04-26 321
2018-04-27 789 2018-04-27 3125
I would phrase your problems using a join of two subqueries:
SELECT
t1.date,
t1.url_cnt,
COALESCE(t2.ip_cnt, 0) AS ip_cnt
FROM
(
SELECT date, COUNT(*) url_cnt
FROM sh_url
GROUP BY date
) t1
LEFT JOIN
(
SELECT date, COUNT(*) ip_cnt
FROM tracking
GROUP BY date
) t2
ON t1.date = t2.date;
When you use a subquery as a value, it can only return one row and one column. You need to use a JOIN:
SELECT urls.date, urls.count AS sh_count, ip.count AS ip_count
FROM (SELECT date(date) AS date, COUNT(*) AS count FROM sh_url GROUP BY date(date)) AS urls
JOIN (SELECT date(date) AS date, COUNT(*) AS count FROM tracking GROUP BY date(date)) AS ip
ON urls.date = ip.date
I have this MySQL table:
ID Number Date
1 4 2015-05-30
2 4 2016-03-15
3 5 2016-04-01
4 5 2016-05-01
I want to get unique Number but only get those with the highest date. The result must get ONLY:
ID Number Date
2 4 2016-03-15
4 5 2016-05-01
I tried:
SELECT
*
FROM emp_events ee
Date = (SELECT MAX(Date) FROM emp_events ee1 WHERE ee1.Number = ee.Number));
but not getting all the desired results.
One way you can accomplish through INNER JOIN
SELECT
E.*
FROM emp_events E
INNER JOIN(
SELECT
Number,
MAX(Date) max_date
FROM emp_events ee
GROUP BY Number
) AS t
ON E.Number = t.Number AND E.Date = t.max_date
Another way could be using IN:
SELECT
E.*
FROM emp_events E
WHERE (E.Number,E.Date) IN
(
SELECT
Number,
MAX(Date) max_date
FROM emp_events ee
GROUP BY Number
)
Try This
You have to GROUP BY number and also to find max date set ORDER BY date ASC in Query
SELECT e.*
FROM(
SELECT ee.*
FROM `emp_events` AS ee
ORDER BY ee.date ASC
) AS e
GROUP BY e.number
Given a table (daily_sales) with say 100k rows of the following data/columns:
id rep sales date
1 a 123 12/15/2011
2 b 153 12/15/2011
3 a 11 12/14/2011
4 a 300 12/13/2011
5 a 120 12/12/2011
6 b 161 11/15/2011
7 a 3 11/14/2011
8 c 13 11/14/2011
9 c 44 11/13/2011
What would be the most efficient way to write a report (completely in SQL) showing the two most recent entries (rep, sales, date) for each name, so the output would be:
a 123 12/15/2011
a 11 12/14/2011
b 153 12/15/2011
b 161 11/15/2011
c 13 11/14/2011
c 44 11/13/2011
Thanks!
FYI, your example is using mostly reserved words and makes it horrid for us to attempt to program against. If you've got the real table columns, gives those to us. This is postgres:
select name,value, max(date)
from the_table_name_you_neglect_to_give_us
group by 1,2
That'll give you a list of first name,value,max(date)...though I gotta ask why give us a column called value if it doesn't change in the example?
Lets say you do have an id column...we'll be consistent with your scheme and call it 'ID'...
select b.id from
(select name,value, max(date) date
from the_table_name_you_neglect_to_give_us
group by 1,2) a
inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value and a.date = b.date
This gives a list of all ID's that are the max...put it together:
select name,value, max(date)
from the_table_name_you_neglect_to_give_us
group by 1,2
union all
select name,value, max(date)
from the_table_name_you_neglect_to_give_us
where id not in
(select b.id from
(select name,value, max(date) date
from the_table_name_you_neglect_to_give_us
group by 1,2) a
inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value and a.date = b.date)
Hoping my syntax is right...should be close at any rate. I'd put a bracket around that entire thing then select * from (above query) order by name...gives you the order you want.
For MySQL, explained in #Quassnoi's blog, an index on (name, date) and using this:
SELECT t.*
FROM (
SELECT name,
COALESCE(
(
SELECT date
FROM tableX ti
WHERE ti.name = dto.name
ORDER BY
ti.name, ti.date DESC
LIMIT 1
OFFSET 1 --- this is set to 2-1
), CAST('1000-01-01' AS DATE)) AS mdate
FROM (
SELECT DISTINCT name
FROM tableX dt
) dto
) tg
, tableX t
WHERE t.name >= tg.name
AND t.name <= tg.name
AND t.date >= tg.mdate
If I understand what you mean.. Then this MIGHT be helpful:
SELECT main.name, main.value, main.date
FROM tablename AS main
LEFT OUTER JOIN tablename AS ctr
ON main.name = ctr.rname
AND main.date <= ctr.rdate
GROUP BY main.name, main.date
HAVING COUNT(*) <= 2
ORDER BY main.name ASC, main.date DESC
I know the SQL is shorter than the other posts, but just give it a try first..