简体   繁体   中英

SQL query to get data that only show the latest date from tables

I have 3 table as below:

Table User

+---+-----+--------+
| id| name| contact|
+---+-----+--------+
|101| John| 123121 |
|102| Jake| 123122 |
|103|  Mia| 123123 |
|104| Mike| 123124 |
|105|Drake| 123125 |
|106|Jonas| 123126 |
+---+-----+--------+

Table Transaction

+------+--------+-------+
|billno|billdate|user_id|
+------+--------+-------+
|  A001|01/01/18|    101|
|  A002|01/01/18|    102|
|  A003|01/01/18|    103|
|  A004|01/02/18|    101|
|  A005|01/02/18|    105|
|  A006|01/02/18|    102|
|  A007|01/03/18|    105|
|  A008|01/03/18|    106|
|  A009|01/04/18|    101|
|  A010|01/04/18|    103|
|  A011|01/04/18|    106|
+------+--------+-------+

Table Product

+------+-----------+
|billno|productcode|
+------+-----------+
|  A001|       P001|
|  A001|       P002|
|  A001|       P002|
|  A002|       P001|
|  A002|       P003|
|  A003|       P001|
|  A003|       P003|
|  A003|       P004|
|  A004|       P001|
|  A004|       P005|
|  A005|       P001|
|  A005|       P003|
|  A005|       P004|
|  A006|       P001|
|  A007|       P001|
|  A007|       P005|
|  A008|       P002|
|  A008|       P003|
|  A008|       P004|
|  A008|       P005|
|  A009|       P001|
+------+-----------+

This table is an example, there a lot more data on the real table.

If my query is like this:

SELECT user.name, user.contact, transaction.billno, transaction.billdate 
FROM user inner join transaction on user.id = transaction.user_id inner join 
product on transaction.billno = product.billno 
WHERE product.productcode = 'P001' 

it will show all bill no and user that have product code P001.

My question is, how to show only the latest date for the user that have product code P001?

The result should be like this:

1 | John| 123121| A009| 01/04/18
2 |Drake| 123125| A007| 01/03/18
3 | Jake| 123125| A006| 01/02/18

It just take the latest date for that user id that have product code P001.

Hope you guys understand my question. Thanks. :)

Try this query:

select * from (
    select [t].[user_id], [p].billno, [p].productcode, [t].billdate,
           --here we assign "ranks", starting with latest date
           row_number() over (partition by [t].[user_id] order by [t].billdate desc) [rn]
    from (
        --here we filter out by product code, so we will get only P001
        select billno, productcode from Product where productcode = 'P001'
    ) [p]
    join [Transaction] [t] on [p].billno = [t].billno
) [a] where [rn] = 1

Your current attempt seems work, just add top(1) with ties clause to display most recent bills for each user

select top(1) with ties u.id, u.name, u.contact, t.billno, t.billdate
from User u inner join Transaction t on t.user_id = u.id
            inner join Product p on p.billno = t.billno
where p.productcode = 'P001'
order by row_number() over (partition by u.id order by t.billdate desc)
SELECT user.name, 
       user.contact, 
       transaction.billno, 
       MAX(transaction.billdate)
FROM user
INNER JOIN transaction ON user.id = transaction.user_id 
INNER JOIN product ON transaction.billno = product.billno 
WHERE product.productcode = 'P001' 
GROUP BY user.name,
         user.contact
         transaction.billno;

You can apply on DateTime data types MIN([col_name]) & MAX([col_name]) and the DBMS sorts them in order -ASC by default-,

However do not forget to use GROUP BY to group other columns you placed after the select clause

Another approach

SELECT TOP 1 user.name, 
             user.contact, 
             transaction.billno, 
             MAX(transaction.billdate)
FROM user
INNER JOIN transaction ON user.id = transaction.user_id 
INNER JOIN product ON transaction.billno = product.billno 
WHERE product.productcode = 'P001'
ORDER BY transaction.billdate DESC;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM