I Have this table named Transaction :
And i am trying to make a SQL query on acess that would find, for each product, the most recent date associated. The results should look like this : (i want to see the quantity as well as the date and product name)
Thanks
Consider filtering with a subquery:
select t.*
from transactions t
where t.date = (
select max(t1.date)
from transactions t1
where t1.product = t.product
)
Try with row_number if you are using MySQL 8.0
select
id,
quantity,
date
from
(
select
id,
quantity,
date,
row_number() over (partition by product order by date desc) as rn
from transaction
) subq
where rn = 1
You have to group the rows by product while selecting the latest (max) date:
select t.product, t.quantity, t.date
from transaction t
inner join (
select product, max(date) as MaxDate
from transaction
group by product
) tm on t.product = tm.product and t.date = tm.MaxDate
Related
table1 has 3 columns in my database: id, category, timestamp. I need to query the newest 3 rows from each category:
WITH ranked_rows AS
(SELECT t.*, ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS rn
FROM table1 AS t)
SELECT ranked_rows.* FROM ranked_rows WHERE rn<=3
now I need to add one more condition: select only from the partitions which have at least 3 rows. how to add this condition?
here is another way:
select * from (
SELECT t.*
, ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS rn
, count(*) OVER (PARTITION BY category) AS cnt
FROM table1 AS t
) t
WHERE rn<=3 and cnt>= 3
You could make another CTE of only the categories matching your condition, then join to that:
WITH ranked_rows AS
(
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS rn
FROM table1 AS t
),
categories AS
(
SELECT category
FROM table1
GROUP BY category
HAVING COUNT(*) >= 3
)
SELECT r.* FROM ranked_rows AS r
JOIN categories AS c USING (category)
WHERE r.rn <= 3;
select id, s
from (
select o_user_id as id, sum(total_price) as s
from Orders o
group by o.o_user_id
) as t1
where s = (select max(t1.s) from t1)
it returns a bug said table t1 doesn't exist.
I want to find the id of the user who spends the most money among all of the orders
here is the table of order
That alias is out of scope for the subquery
select id, s
from (
select o_user_id as id, sum(total_price) as s
from Orders o
group by o.o_user_id
) as t1
where s = (select max(t1.s) from t1)
You can do
WITH T1 AS
(
select o_user_id as id, sum(total_price) as s
from Orders o
group by o.o_user_id
)
SELECT id, s
FROM T1
WHERE s = (select max(t1.s) from t1);
If you want only one row, you can use order by and limit:
select o_user_id as id, sum(total_price) as s
from Orders o
group by o.o_user_id
order by s desc
limit 1;
In MySQL 8+, you can use window functions. To get multiple rows in the event of ties, use rank():
select ou.*
from (select o_user_id as id, sum(total_price) as s,
rank() over (order by sum(total_price) desc) as seqnum
from Orders o
group by o.o_user_id
) ou
where seqnum = 1;
thank you in advance for your help.
I have an SQL table which looks like this.
date and serial number are a composite key together. Meaning there cannot be a tuple with the same date and the same serial_number. Now, I want to get the most recent date (transaction) per serial_number. How can I do this? This is what i tried but it gives me some duplicates.
SELECT DATE_FORMAT(`t1`.date,'%m-%d-%y') as date , `t1`.serial_number
FROM table1 `t1`
WHERE date IN (SELECT MAX(date) FROM table1 GROUP BY serial_number)
order by `t1`.date desc, `t1`.serial_number asc;
You need correlated subquery not only subquery :
SELECT DATE_FORMAT(t.date,'%m-%d-%y') as date, t.serial_number
FROM table1 t
WHERE t.date = (SELECT MAX(t1.date)
FROM table1 t1
WHERE t1.serial_number = t.serial_number
)
order by t.date desc, t.serial_number asc;
You could use a inner join on max_date for serial_number
> SELECT DATE_FORMAT(`t1`.date,'%m-%d-%y') as date
> , `t1`.serial_number FROM `table` `t1` INNER JOIN (
> SELECT serial_number, MAX( DATE_FORMAT(`T`.date,'%m-%d-%y')) max_date
> FROM `table` T
> GROUP BY serial_number ) T ON T.serial_number = `t1`.serial_number AND T.max_date = DATE_FORMAT(`t1`.date,'%m-%d-%y')
>
> order by `t1`.date desc, `t1`.serial_number asc;
I'm trying to run a query like this:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id, category
)
UPDATE table SET amount = cte.sum_amount WHERE id = cte.id;
However, I keep getting the error
Unknown column 'cte.id in WHERE clause'
Does anyone know how I can refer to my common table expression in the UPDATE query, or otherwise, rewrite it?
You can try below
WITH cte AS
(
SELECT id, SUM(amount) AS sum_amount FROM t1 GROUP BY category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id
Alternate way with Temporary table, you can read about CTE and Temporary Table
Temporary table:
SELECT id, category, SUM(amount) AS sum_amount
INTO #temp
FROM t1 GROUP BY id, category
Update query with temp table:
UPDATE OT
SET OT.sum_amount= TT.sum_amount
FROM table OT
JOIN #temp TT
ON OT.id = TT.id
CTE:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id,category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id
I want to query above picture.
Left picture is original data, right picture is query data.
select distinct ID, Nickname, Revision
from test_table
This query do not show above picture.
How to avoid duplicate data?
If SQL Server, using window function ROW_NUMBER in subquery:
select t.id, t.nickname, t.revision
from (
select t.*, row_number() over (
partition by t.id order by t.revision desc
) rn
from your_table t
) t
where rn = 1;
Or using TOP with ties with ROW_NUMBER:
select top 1 with ties *
from your_table
order by row_number() over (
partition by id order by revision desc
)
If MySQL:
select t.*
from your_table t
inner join (
select id, MAX(revision) revision
from your_table
group by id
) t1 on t.id = t1.id
and t.revision = t1.revision;
Another trick using TOP 1 with TIES
SELECT Top 1 with ties *
FROM your_table t
Order by row_number() over (partition BY t.id order by t.revision DESC)
select distinct ID, Nickname, MAX(Revision)
from test_table
group by ID