Latest Data based on DateTime or CustMCId - sql

I have a table in which different Clients are assign to different MC. Like Client (84) switch the MC 3 times. Now I want to get the latest MC of Client=84. I make this Query
select max(cstmrMC.CustMCId),cstmrMC.CustId,cstmrMC.MCID,cstmrMC.AssignDate
from CustomerMC cstmrMC
where cstmrMC.CustId=84
group by cstmrMC.CustMCId,cstmrMC.CustId,cstmrMC.MCID,cstmrMC.AssignDate
ORDER BY cstmrMC.CustMCId,cstmrMC.CustId,cstmrMC.MCID,cstmrMC.AssignDate
which shows this result
CustMCId CustId MCID AssignDate
52 84 18 2013-10-01 18:21:56.000
59 84 7 2013-09-09 16:10:06.000
80 84 19 2013-10-09 03:54:00.000
156 84 21 2013-11-11 00:00:00.000
NOw I want only this
156 84 21 2013-11-11 00:00:00.000
How can I get this result????

Use the row_number function to partition and order the customers so that the most recent MCID (based on AssignDate) is first within each customer.
WITH cteCustomers AS (
SELECT CustMCId, CustId, MCID, AssignDate,
ROW_NUMBER() OVER(PARTITION BY CustId ORDER BY AssignDate DESC) AS RowNum
FROM CustomerMC
)
SELECT CustMCId, CustId, MCID, AssignDate
FROM cteCustomers
WHERE RowNum = 1;

Related

SQL query to get records inserted over last 7 days grouped by day

I have a table two very similar tables that store purchases and downloads they both look similar to this with an id and date
id date
1 2020-06-15 18:25:27.415548+01
2 2020-06-15 11:03:30.157502+01
3 2020-06-15 17:09:15.592209+01
4 2020-06-14 18:29:18.332623+01
5 2020-06-13 18:09:31.990473+01
... many more rows ...
I would like to be able execute a Postgres query that returns the count of all the purchases and downloads inserted over the last 7 days grouped by day. An ideal response would look like this
date purchase_count download_count
2020-06-13 37 64
2020-06-14 44 56
2020-06-15 34 63
2020-06-16 41 72
2020-06-17 30 40
2020-06-18 42 55
2020-06-19 9 22
One method uses aggregation with full join:
select dte, coalesce(d.downloads, 00) as downloads, coalesce(p.purchases, 0) as purchases
from (select date_trunc('day', date) as dte, count(*) as downloads
from downloads
group by dte
) d full join
(select date_trunc('day', date) as dte, count(*) as purchases
from purchases
group by dte
) p
using (dte)
order by dte;

Grouping a column in oracle

I have three columns within my table:
Amount, OrderNumber, Customerid
For each customerid there will be ordernumber and amount.
Now i need to display customerid,Ordernumber and Amount(total Amount- for each customerid).
custid srcnumber amount
112 4344 20
112 7678 10
112 8766 30
34 6577 15
34 4566 5
Expected:
custid srcnumber amount
112 4344 60
112 7678 60
112 8766 60
34 6577 20
34 4566 20
Use sum() over (partition by ..) analytic function to sum up the amount per each row :
select Customerid as custid,
OrderNumber as srcnumber,
sum(amount) over ( partition by Customerid ) as amount
from tab
order by custid desc
Demo

Max 3 values of every group

I sorted my data to something like this and now I want to get top 3 max person_occurence by every company but I couldn't figure out how to do it.
person_occurence company person_id
67 company_1 110
66 company_2 176
64 company_3 100
64 company_3 196
63 company_4 127
62 company_1 150
61 company_5 120
60 company_3 140
59 company_5 154
59 company_5 162
59 company_4 194
58 company_4 109
58 company_3 128
58 company_1 156
I used this query to get max of every company but can't get top 3 max person_occurence
SELECT max(agent_occurence), company FROM table GROUP BY company;
Use window functions:
select t.*
from (select t.*,
row_number() over (partition by company order by person_occurrence desc) as seqnum
from t
) t
where seqnum <= 3;
Now, this assumes that you want the top 3 regardless of ties -- that is, if 4 are tied with the same highest value, this returns three of them. Ties make things more difficult. You may want dense_rank() or rank() instead.
You can use correlated subquery :
SELECT t1.*
FROM table t1
WHERE t1.person_occurencee = (SELECT max(t2.person_occurence) FROM table t2 WHERE t1.company = t2.company);
If your DBMS supports analytical function then you can also do :
select t.*
from (select t.*,
rank() over (partition by company order by person_occurrence desc) as seq
from t
) t
where seq <= 3;

How to select rows based on condition

The following is the code snippet.
Just design purpose I have added.
Here The user will be assigned multiple group.
So I want to select the person details alone.
Here Person id 103 have two different persmission for the same Product.
But the higher permission only be selected for the person.
But if he is not assinged to multiple group, the default permission should be selected.
Sample data
ProdId PersonId GroupId Permission
10103 78 55 15
10103 99 33 15
10103 100 33 0
10103 103 33 15
10103 103 40 0
10103 112 33 15
Result data should be
ProdId PersonId Permission
10103 78 15
10103 99 15
10103 100 0
10103 103 15
10103 112 15
You should use ROW_NUMBER() :
SELECT * FROM (
SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY t.prodid,t.personID ORDER BY t.permission DESC) as rnk
FROM YourTable t) s
WHERE s.rnk = 1
I assumed you want the highest number on permission by your example? If not, change the ORDER BY clause to what you want.
Right now it will select all columns, specify the ones you want.
If you are using Oracle, try the below query..
select * from (
select ProdID, PersonID, Permission, row_number() over (partition by PersonID order by Permission Desc) as column1 from table1)
where column1 = 1;

Sql get latest records of the month for each name

This question is probably answered before but i cant find how to get the latest records of the months.
The problem is that I have a table with sometimes 2 row for the same month. I cant use the aggregate function(I guess) cause in the 2 rows, i have different data where i need to get the latest.
Example:
name Date nuA nuB nuC nuD
test1 05/06/2013 356 654 3957 7033
test1 05/26/2013 113 237 399 853
test3 06/06/2013 145 247 68 218
test4 06/22/2013 37 37 6 25
test4 06/27/2013 50 76 20 84
test4 05/15/2013 34 43 34 54
I need to get a result like:
test1 05/26/2013 113 237 399 853
test3 06/06/2013 145 247 68 218
test4 05/15/2013 34 43 34 54
test4 06/27/2013 50 76 20 84
** in my example the data is in order but in my real table the data is not in order.
For now i have something like:
SELECT Name, max(DATE) , nuA,nuB,nuC,nuD
FROM tableA INNER JOIN
Group By Name, nuA,nuB,nuC,nuD
But it didn't work as i want.
Thanks in advance
Edit1:
It seems that i wasn't clear with my question...
So i add some data in my example to show you how i need to do it.
Thanks guys
Use SQL Server ranking functions.
select name, Date, nuA, nuB, nuC, nuD from
(Select *, row_number() over (partition by name, datepart(year, Date),
datepart(month, Date) order by Date desc) as ranker from Table
) Z
where ranker = 1
Try this
SELECT t1.* FROM Table1 t1
INNER JOIN
(
SELECT [name],MAX([date]) as [date] FROM Table1
GROUP BY [name],YEAR([date]),MONTH([date])
) t2
ON t1.[date]=t2.[date] and t1.[name]=t2.[name]
ORDER BY t1.[name]
Can you not just do an order
select * from tablename where Date = (select max(Date) from tablename)
followed by only pulling the first 3?