I have 3 tables:
table user
table activity a
table activity b
I want to retrieve all the data in the user table and all the last data in the table of activities a and b, like this :
how do i do sql writing?
In MySQL, I would recommend using row_number() and left join:
select u.*, a.*, b.*
from user u left join
(select a.*,
row_number() over (partition by id_user order by date_a desc) as seqnum
from a
) a
on a.id_user = u.id_user and a.seqnum = 1 left join
(select b.*,
row_number() over (partition by id_user order by date_b desc) as seqnum
from b
) b
on b.id_user = u.id_user and b.seqnum = 1;
Related
I have the following query:
SELECT a.*
FROM `user_subscription_history` a
LEFT JOIN `transaction` b ON b.tran_date=a.date_time
b.tran_date and a.date_time are both timestamps. I'd like the join to return the closest matching. Currently only returns if matching.
How do i solve this?
You can use ROW_NUMBER() to identify the closest timestamp of another table:
select *
from (
select a.*,
row_number() over(
order by abs(timestampdiff(microsecond, b.tran_date, a.date_time))
) as rn
from user_subscription_history a
cross join `transaction` b
) x
where rn = 1
I want to do a query where for each diagnostic code - ID (this is a column), select the name of the most common medication - p_name (another column) used to treat that condition i.e., the medication name that more often appears associated to prescriptions (table) for that diagnosis.
This is the structure of my prescription table:
| p_name | lab | doctor_VAT | date_timestamp | ID | dosage | prescription_description |
I started by making a query to count the tuple pairs p_name and ID:
SELECT DISTINCT p.ID,
p.p_name,
COUNT(*) OVER (PARTITION BY p.p_name, p.ID) AS Cnt
FROM prescription AS p
ORDER BY Cnt DESC
And then to this I tried to apply the "greatest_n_per_group" problem to this
(SQL select only rows with max value on a column):
FROM (SELECT DISTINCT p.ID,
p.p_name,
COUNT(*) OVER (PARTITION BY p.p_name, p.ID) AS Cnt
FROM prescription AS p
ORDER BY Cnt DESC) as Tabela
INNER JOIN(
SELECT Tabela2.ID, MAX(Tabela2.Cnt)
FROM (SELECT DISTINCT p.ID,
p.p_name,
COUNT(*) OVER (PARTITION BY p.p_name, p.ID) AS Cnt
FROM prescription AS p
ORDER BY Cnt DESC) as Tabela2
GROUP BY Tabela2.ID
)
But this produces errors, am I going at this the right the way? do you suggest a different method?
Since your MySQL supports Window function, You can simply use -
SELECT ID, p_name
FROM (SELECT ID, p_name, RANK() OVER(PARTITION BY ID ORDER BY CNT DESC) RNK
FROM (SELECT ID,
p_name,
COUNT(*) CNT
FROM prescription
GROUP BY ID,
p_name
) T1
) T2
WHERE RNK = 1
You need FROM ( ) T in this case T is the table name alias for the FROM subquery clause
FROM (SELECT DISTINCT p.ID,
p.p_name,
COUNT(*) OVER (PARTITION BY p.p_name, p.ID) AS Cnt
FROM prescription AS p
ORDER BY Cnt DESC) as Tabela
INNER JOIN(
SELECT Tabela2.ID, MAX(Tabela2.Cnt)
FROM (SELECT DISTINCT p.ID,
p.p_name,
COUNT(*) OVER (PARTITION BY p.p_name, p.ID) AS Cnt
FROM prescription AS p
ORDER BY Cnt DESC) as Tabela2
GROUP BY Tabela2.ID
) T
SELECT
p1.ID,
(SELECT TOP 1 p2.p_name
FROM prescription AS p2
WHERE p2.ID=p1.ID
GROUP BY p2.p_name
ORDER BY count(*) DESC) as MostUsed
FROM prescription AS p1
GROUP BY p1.ID
Above is for MSSQL, below is for MySQL
SELECT
p1.ID,
(SELECT p2.p_name
FROM prescription AS p2
WHERE p2.ID=p1.ID
GROUP BY p2.p_name
ORDER BY count(*) DESC
LIMIT 1) as MostUsed
FROM prescription AS p1
GROUP BY p1.ID
dbfiddle
I wrote this:
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN (SELECT *
FROM T
WHERE T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC
LIMIT 10)
and I receive this
"Unknown column 'T1.CATEGORY' in 'where clause'".
Why?
Update:
My purpose of this is to get 10 posts of any category.
Because T1 is not visible from within the subquery.
Your JOIN also serves no purpose and/or you probably forgot the JOIN condition.
In JOIN condition should use ON keyword
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN SELECT * FROM T ON T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC LIMIT 10;
If you need to get 10 posts of each category you can use a query like this:
SELECT CATEGORY, Post
FROM (
SELECT a.CATEGORY, a.Post, count(*) as rn
FROM #T a
JOIN #T b ON a.CATEGORY = b.CATEGORY AND a.Post >= b.Post
GROUP BY a.CATEGORY, a.Post) dt
WHERE rn < 11;
I have the following query:
SELECT
a.name, a.address, n.date, n.note
FROM a
LEFT JOIN n ON a.id = n.id
The a.id has a one to many relationship with n.id, so that many notes can be assocaited with one name.
How do I return just the latest note for each name instead of all the notes?
I'm using SQL Server 2008.
Thanks.
Here's one way using ROW_NUMBER()
SELECT t.name, t.address, t.date, t.note
FROM (
SELECT
a.name, a.address, n.date, n.note,
ROW_NUMBER() OVER (PARTITION BY a.name ORDER BY n.date DESC) rn
FROM a
LEFT JOIN n ON a.id = n.id
) t
WHERE t.rn = 1
alternative you can use a correlated subquery too get the max date, something like this
SELECT
a.name, a.address, n.date, n.note
FROM a
LEFT JOIN n ON a.id = n.id
WHERE n.date = (SELECT MAX(nn.date)
FROM n AS nn
WHERE a.id = nn.id)
I am new to SQL and I want to fetch 5th highest value without using LIMIT. Here is the code I am trying but it is not working properly. It is showing the 5th lowest value instead of 5th highest value.
SELECT a . * FROM user AS a
WHERE 5 =
(SELECT count( DISTINCT b.id ) FROM user AS b WHERE b.id >= a.id ORDER BY a.id DESC)
Can anyone help me with this?
You could also do:
SET #nth := 5;
SELECT
a.*
FROM jos_modules AS a
WHERE #nth = (
SELECT
COUNT(b.id)
FROM user AS b
WHERE
a.id >= b.id
);
Try this
SELECT a . *
FROM user AS a
WHERE 5 = (
SELECT count( DISTINCT b.id )
FROM user AS b
WHERE a.id >= b.id ORDER BY a.id )
select * from (
select a.* , row_number() over (order by id asc) as RANK
from a ) where RANK=5 ;
If you are using a Teradata DB , you can use qualify statement :
select * from a
qualify row_number () over(order by id asc)=5;