I have three status of an order as Entered,Aw Appr & Completed in my table. Entered and Completed have one row each while AW Appr repeat on weekly basis till the order got completed. Now all three status but only once. AW Appr should be latest one. I am using this query, but it's giving only maximum month and max week data. It's pick available max week of complete data instated latest entry. Please help to enhance query to fetch all three status and AW Appr only latest one.
Source Table
http://sqlfiddle.com/#!18/67924/2
SELECT DISTINCT t1.Contract_Number
,t2.D_Monthx
,t2.D_Reporting_Week
,t2.D_Status
FROM Table1 t1
INNER JOIN (
SELECT DISTINCT max(D_Monthx) D_Monthx
,Max(D_Reporting_Week) D_Reporting_Week
,D_Status
,Contract_Number
FROM Table1
GROUP BY Contract_Number
,D_Status
) t2 ON t1.Contract_Number = t2.Contract_Number
AND t1.D_Monthx = t2.D_Monthx
WHERE t1.Contract_Number = '130100964/2'
Result Should be -
Using Row_Number()
Select Contract_Number, D_Monthx, D_Reporting_Week, D_Status from
(Select *,
Row_Number() over
(partition by Contract_Number,D_Status order by D_Monthx desc)
as ranking
from Table1)c
where ranking=1
SqlFiddle
We can try using ROW_NUMBER here for a straightforward solution:
SELECT Contract_Number, D_Monthx, D_Reporting_Week, D_Status
FROM
(
SELECT D_Monthx, D_Reporting_Week, D_Status, Contract_Number,
ROW_NUMBER() OVER (PARTITION BY Contract_Number, D_Status
ORDER BY D_Reporting_Week DESC) rn
FROM yourTable
) t
WHERE rn = 1;
Demo
Row number works well here, because for the Entered and Completed statuses would only ever appears once, meaning their row numbers would always be one. Similarly, the row number for the most recent AW Appr which we want to select would also be one.
Related
I am still learning SQL. Currently, I was able to get row number from partitioning and row_number()
However, I am stuck where I can't think of a way to select the highest row_num in order to view only the records with latest update.
I get invalid column name at the end. I apologize for the messy structure, I plan to clean it up better.
Thank you in advance for any answers/hints from you guys. I appreciate your time.
Edit: The latest update is actually the highest row_num return rather than 1. I forgot to specify.
FROM
(
SELECT
a.DELFLAG,
a.fname,
a.lname,
a.key1,
l.key2,
l.update,
ROW_NUMBER() OVER(PARTITION BY key1, key2 ORDER BY l.lupdate DESC) AS row_num
FROM dbo.t1 a
INNER JOIN dbo.t2 i ON i.key1 = a.key1
INNER JOIN dbo.t3 l ON l.key1 = i.key1
) AS K
WHERE
[row_num] = SELECT MAX([row_num]) AS latest)
AND
DELFLAG = 0
Edit 2: Since a record could be updated multiple times on the same day but only the last row number reflected the latest update.
You could calculate the maximum row number by just using count() and then using that in the where clause:
COUNT(*) OVER (PARTITION BY key1, key2) AS cnt
And then:
WHERE cnt = row_num
This assumes that you want one row per pair of key1/key2.
This is your code:
WHERE
[row_num] = SELECT MAX([row_num]) AS latest)
Most likely, you want:
WHERE
[row_num] = 1
Rationale: row_number() ranks records within partitions; in your code, it assigns rank 1 to the record with the max l.update for each (key1, key2) tuple. These are the records you want to retain, so... Just filter on [row_num] = 1.
On the other hand, if you want the earliest record per partition, then use an ascending sort in the order by clause of the window function rather than a descending sort:
ROW_NUMBER() OVER(PARTITION BY key1, key2 ORDER BY l.lupdate) as row_num
The outer query still filters on row_num = 1.
In SQL Server, I am attempting to pull the second latest NOTE_ENTRY_DT_TIME (items highlighted in screenshot). With the query written below it still pulls the latest date (I believe it's because of the grouping but the grouping is required to join later). What is the best method to achieve this?
SELECT
hop.ACCOUNT_ID,
MAX(hop.NOTE_ENTRY_DT_TIME) AS latest_noteid
FROM
NOTES hop
WHERE
hop.GEN_YN IS NULL
AND hop.NOTE_ENTRY_DT_TIME < (SELECT MAX(hope.NOTE_ENTRY_DT_TIME)
FROM NOTES hope
WHERE hop.GEN_YN IS NULL)
GROUP BY
hop.ACCOUNT_ID
Data sample in the table:
One of the "easier" ways to get the Nth row in a group is to use a CTE and ROW_NUMBER:
WITH CTE AS(
SELECT Account_ID,
Note_Entry_Dt_Time,
ROW_NUMBER() OVER (PARTITION BY AccountID ORDER BY Note_Entry_Dt_Time DESC) AS RN
FROM dbo.YourTable)
SELECT Account_ID,
Note_Entry_Dt_Time
FROM CTE
WHERE RN = 2;
Of course, if an ACCOUNT_ID only has 1 row, then it will not be returned in the result set.
The OP's statement "The row will not always be 2." from the comments conflicts with their statement "I am attempting to pull the second latest NOTE_ENTRY_DT_TIME" in the question. At a best guess, this means that the OP has rows with the same date, that could be the "latest" date. If so, then would simply need to replace ROW_NUMBER with DENSE_RANK. Their sampple data, however, doesn't suggest this is the case.
You can use window functions:
select *
from (
select
n.*,
row_number() over(partition by account_id order by note_entry_dt_time desc) rn
from notes n
) t
where rn = 2
I have 2 tables and I'm trying to combine them, while removing duplicate entries, I only want to get the last submitted date per month.
unfortunately I was not able to get this working
a.[Region],
a.[Country],
a.[site],
a.[Account Type],
q.[month],
q.[account],
q.[metric],
q.[Goal],
q.[Unit],
q.[Actual],
q.[Waived],
q.[Weight],
q.[Achieved],
q.[SubmittedDateTime]
from [accountTable] a right join [scoreTable] q, (select
max(q.[SubmittedDateTime]) as max_date
group by q.[Month]) on a.[account] = q.[account]
This following script will return you Account/Year/Month wise Last submitted date. I have added Account in consideration as you Joined both table. If only Month wise last submitted is required, I am confused why you need to join tables as Month wise results can be retrieve only from scoreTable!
SELECT a.[account],
YEAR(SubmittedDateTime),
MONTH(SubmittedDateTime),
MAX(SubmittedDateTime)
FROM [accountTable] a
INNER JOIN [scoreTable] q
ON a.[account] = q.[account]
GROUP BY .[account],
YEAR(SubmittedDateTime),
MONTH(SubmittedDateTime)
ORDER BY 1,2,3
You can use row_number() to enumerate the rows within each month and just choose the last one:
select s.*, a.region, a.country, a.site
from (select s.*,
row_number() over (partition by s.account, year(s.submitteddatetime), month(s.submitteddatetime)
order by submitteddatetime desc
) as seqnum
from scoreTable s
) s join
accountTable a
on a.account = s.account
where s.seqnum = 1;
I need to grab the latest version of every row to not get duplicate data. "_sdc_sequence" is a unix epoch attached to the record during replication and determine the order of all the versions of a row.
I would like to get cost and impressions fro each campaign everyday
I have tried to use INNER JOIN but I could not get the data. when I tried to use "account" and "clientname" for attribute (every row has the same clientname and account) I got cero in cost and impressions. Maybe the attributes are wrongs
SELECT DISTINCT day, cost, impressions, campaign
FROM `adxxxxx_xxxxxxxx` account
INNER JOIN (
SELECT
MAX(_sdc_sequence) AS seq,
campaignid
FROM `adxxxxx_xxxxxxxx`
GROUP BY campaignid) clientname
ON account.campaignid = clientname.campaignid
AND account._sdc_sequence = clientname.seq
ORDER by day
There is another way to do this? or How I can fix it?
thank you
#standardSQL
SELECT row.* FROM (
SELECT ARRAY_AGG(t ORDER BY _sdc_sequence DESC LIMIT 1)[OFFSET(0)] row
FROM `adxxxxx_xxxxxxxx` t
GROUP BY campaignid
)
I have a table 'Cashup_Till' that records all data on what a particular till has recorded in a venue for a given day, each venue has multiple tills all with a designated number 'Till_No'. I need to get the previous 2 days entries for each till number. For each till Individually I can do this...
SELECT TOP 2 T.* FROM CashUp_Till T
WHERE T.Till_No = (Enter Till Number Here)
ORDER BY T.Till_Id DESC
Some venues have 20-30 tills so Ideally I need to do all the tills in one call. I can pass in a user defined table type of till numbers, then select them in a subquery, but that's as far as my SQL knowledge takes me, does anyone have a solution?
Here is one way:
SELECT T.*
FROM (SELECT T.*,
ROW_NUMBER() OVER (PARTITION BY Till_No ORDER BY Till_Id DESC) as seqnum
FROM CashUp_Till T
) T
WHERE seqnum <= 2;
This assumes that there is one record per day, which I believe is suggested by the question.
If you have a separate table of tills, then:
select ct.*
from t cross apply
(select top 2 ct.*
from cashup_till ct
where ct.till_no = t.till_no
order by till_id desc
) ct;