Group by a set of Values (Check-In or Check-Out) - sql-server

I have a simple table which records people clocking-in and clocking out like so.
Id | EmployeeNumber | InOutId | InOutDateTime
-----------------------------------------------------
1 | 505 | IN | 2015-03-24 08:32:42:000
1 | 506 | IN | 2015-03-24 08:35:47:000
1 | 507 | IN | 2015-03-24 08:46:12:000
1 | 505 | OUT | 2015-03-24 16:59:00:000
1 | 506 | OUT | 2015-03-24 17:05:00:000
I want to show the total people currently IN and those currently OUT. In other words:
- Total IN means those that do not have a corresponding OUT for that given day. - Total OUT means those that do have an IN and an OUT for that given day.
So, based on my table above, I want to get the following results:
TotalCurrentlyIn | TotalCurrentlyOut
-----------------------------------------
1 | 2
This is what I have so far:
DECLARE #d date;
set #d = cast('2015-03-24 15:02:42.000' as date)
select EmployeeNumber, InOutId, InOutDateTime from MyAttendance
where
InOutDateTime >= DATEADD(day, DATEDIFF(day, 0, #d), 0)
and InOutDateTime < DATEADD(day, DATEDIFF(day, 0, #d) +1, 0)
order by
EmployeeNumber, InOutId
I need to be able to sum and group by - any ideas?

try,
DECLARE #d date;
set #d = cast('2015-03-24 15:02:42.000' as date)
;with cte as(
select t.EmployeeNumber,t.InOutId as in1,
t1.InOutId out1,t.InOutDateTime from #t t
left join (select EmployeeNumber,InOutId,InOutDateTime from #t
where InOutId='OUT' and cast(InOutDateTime as date)=cast(#d as date) ) t1
on t.EmployeeNumber=t1.EmployeeNumber and
cast(t.InOutDateTime as date)=cast(t1.InOutDateTime as date)
where t.InOutId='IN' and cast(t.InOutDateTime as date)=cast(#d as date))
select count(in1) Totalin,count(out1) Totalout, sum(case when out1 is null then 1 else 0 end) TotalCurrentlyIn
,count(out1) TotalCurrentlyOut from cte
data
declare #t table (Id int,EmployeeNumber int, InOutId varchar(3), InOutDateTime datetime)
insert into #t(Id, EmployeeNumber,InOutId, InOutDateTime) values
(1 , 505 , 'IN' , '2015-03-24 08:32:42:000'),
(1 , 506 , 'IN' , '2015-03-24 08:35:47:000'),
(1 , 507 , 'IN' , '2015-03-24 08:46:12:000'),
(1 , 505 , 'OUT' , '2015-03-24 16:59:00:000'),
(1 , 506 , 'OUT' , '2015-03-24 17:05:00:000')

CheckIn = 1 and CheckOut = 2 so you need to check last entry of all the uses.
Select EmployeeId, ActionType, Max(ActionDateTime)
From AttendanceLog
Where
ActionDateTime >= DATEADD(day, DATEDIFF(day, 0, #d), 0)
and ActionDateTime < DATEADD(day, DATEDIFF(day, 0, #d) +1, 0)
Group by
EmployeeId, ActionType
Order by
EmployeeId,ActionType

If I understand the question. you need to know how much person is in the office right now:
the first query return the max date for any employee, than you join it with the actionType
select
EmployeeId , max(ActionDateTime) as MaxActionDateTime into #temptable
from table
group by EmployeeId
select count (EmployeeId), ActionType
from table inner join #temptable
on table.EmployerId == #temptable.EmployerId
and table.ActionDateTime == #temptable.MaxActionDateTime
group by ActionType

Using a windowing function you can get the last action for every employee and count those
With data As (
Select id, EmployeeNumber, InOutId
, lastAction = ROW_NUMBER() OVER (PARTITION BY EmployeeNumber
ORDER BY InOutDateTime DESC)
From table1
)
Select Count(CASE InOutId WHEN 'IN' THEN 1 END) TotalCurrentlyIn
, Count(CASE InOutId WHEN 'OUT' THEN 1 END) TotalCurrentlyOut
From data
Where lastAction = 1

Related

Locate items with no changes over a period of time

Is there a T-SQL query that would allow me to see products that have had no changes in quantity for the past 4 days?
Product
Date
Quantity
Coke
2022-04-06
0
Coke
2022-04-07
0
Coke
2022-04-08
0
Coke
2022-04-09
0
Pepsi
2022-04-06
0
Pepsi
2022-04-07
1
Pepsi
2022-04-08
1
Pepsi
2022-04-09
1
Sprite
2022-04-06
1
Sprite
2022-04-07
0
Sprite
2022-04-08
0
Sprite
2022-04-09
1
Tango
2022-04-05
2
Tango
2022-04-06
1
Tango
2022-04-07
1
Tango
2022-04-08
1
Tango
2022-04-09
1
Result
Product
Quantity
Coke
0
Edit: this is how I started off my code
DECLARE #CurrentDate date = GETDATE();
DECLARE #PreviousDate date = DATEADD (Day, -4, #CurrentDate)
DECLARE #Quantity AS Decimal(8,5)
DECLARE #Count AS int
SELECT
[Date], [Product], [Quantity]
FROM
Table1
WHERE
[Date] = #PreviousDate
AND [Product] IN (SELECT [Product]
FROM Table1
WHERE [DATE] BETWEEN #PreviousDate AND #CurrentDate)
If I understand correctly you could use first_value() analytic function to partition the products accordingly and check the first and last quantities match,
select distinct product, quantity from (
select *,
First_Value(quantity) over(partition by product order by date) f,
First_Value(quantity) over(partition by product order by date desc) l
from t
where date >= DateAdd(day,-4,GetDate())
)t
where f = l;
Demo Fiddle
Edit
Seems I didn't quite understand but do now (I hope) so how about an approach using not exists?
with cv as (
select *,
First_Value(quantity) over(partition by product order by date desc) currentValue,
Count(*) over(partition by product) qty
from t
where date >= DateAdd(day,-4,GetDate())
)
select distinct product, quantity
from cv t
where qty=4 and not exists (
select * from cv t2
where t2.product = t.product
and t2.quantity != currentValue
);
Demo Fiddle (2)
You select all records from #PreviousDate (WHERE [Date] = #PreviousDate) and which have modifications (AND [Product] IN (...))
SELECT
t1.[Date], t1.[Product], t1.[Quantity], t2.Quantity "PreviousQuantity"
FROM
Table1 t1
LEFT JOIN Table1 t2 On t1.Product = t2.Product and t2.[Date] = #PreviousDate
WHERE t1.[Date] = #CurrentDate
and t1.Quantity = t2.Quantity
But this will show nothing because #PreviousDate has the value 2022-04-05 (when #CurrentDate=2022-04-09)
So, you might need to change #PreviousDate to: DECLARE #PreviousDate date = DATEADD (Day, -3, #CurrentDate)
see: DBFIDDLE

Referencing the current row outer apply column within separate outer join

Recently I've been tasked with creating a report that outputs sales information by Date of Business and Hour of the Day.
Here is the query I have currently written.
WITH CTE AS
(
SELECT 0 AS Count
UNION ALL
SELECT Count + 1
FROM CTE
WHERE Count + 1 <= 23
),
ALLDATES AS
(
SELECT CONVERT(datetime, #startDate) AS [DOB]
UNION ALL
SELECT DATEADD(DAY, 1, [DOB])
FROM AllDates
WHERE [DOB] < #endDate
)
SELECT D.DOB, A.Count AS [Hour], CONCAT(A.Count, ':00') AS [DisplayHour]
, B.OrderModeName, COALESCE(B.Sales_Total, 0) AS [Sales]
, COALESCE(B.Comps, 0) AS Comps, COALESCE(B.Promos, 0) AS Promos
FROM CTE AS A
OUTER APPLY (SELECT DOB FROM ALLDATES) D
LEFT OUTER JOIN (
SELECT DATEPART(HH, ItemDetail.TransactionTime) AS [Hour]
, OrderMode.OrderModeName, SUM(ItemDetail.GrossPrice) Sales_Total
, SUM(CompAmount) AS Comps, SUM(PromoAmount) AS Promos
FROM ItemDetail
INNER JOIN OrderMode ON OrderMode.OrderModeID = ItemDetail.OrderModeID
WHERE ItemDetail.DOB = D.DOB /*NEED HELP HERE*/ AND LocationID IN (
SELECT LocationID
FROM LocationGroupMember
WHERE LocationGroupID = '#locationGroupID'
)
GROUP BY ItemDetail.DOB, DATEPART(HH, ItemDetail.TransactionTime), OrderMode.OrderModeName
) AS B
ON A.Count = B.Hour
ORDER BY D.DOB, A.Count
Where I am struggling is being able to reference the current row's DOB column that is coming from the OUTER APPLY.
I have tried WHERE ItemDetail.DOB = D.DOB, however I receive an error that the identifier can't be bound. Am I correct that in understanding that the outer applied data is not visible to the subquery within the join?
Here is an example of the output I'm expecting:
DOB | Hour | Display Hour | OrderModeName | Sales | Comps | Promos
1/8/2020 | 17 | 17:00 | Order | 163.17 | 0 | 0 <-- Sales for Hour and Order Mode present
1/8/2020 | 23 | 23:00 | | 0 | 0 | 0 <-- No sales at all for a given hour
Thanks in advance for any direction and advice!
The basic pattern here is to CROSS JOIN to define the result "grain" and then LEFT JOIN the fact table to populate the rows for which data exists. EG
WITH CTE AS
(
SELECT 0 AS Count
UNION ALL
SELECT Count + 1
FROM CTE
WHERE Count + 1 <= 23
),
ALLDATES AS
(
SELECT CONVERT(datetime, #startDate) AS [DOB]
UNION ALL
SELECT DATEADD(DAY, 1, [DOB])
FROM AllDates
WHERE [DOB] < #endDate
),
ALLHOURS as
(
SELECT D.DOB, A.Count AS [Hour], CONCAT(A.Count, ':00') AS [DisplayHour]
FROM CTE AS A
CROSS JOIN ALLDATES D
),
ITEM_SUMMARY as
(
SELECT DOB, DATEPART(HH, ItemDetail.TransactionTime) AS [Hour], OrderMode.OrderModeName, SUM(ItemDetail.GrossPrice) Sales_Total, SUM(CompAmount) AS Comps, SUM(PromoAmount) AS Promos
FROM ItemDetail
INNER JOIN OrderMode ON OrderMode.OrderModeID = ItemDetail.OrderModeID
AND LocationID IN (SELECT LocationID FROM LocationGroupMember WHERE LocationGroupID = #locationGroupID)
where DOB >= #startDate
and DOB < #endDate
GROUP BY ItemDetail.DOB, DATEPART(HH, ItemDetail.TransactionTime), OrderMode.OrderModeName
)
select ALLHOURS.DOB,
ALLHOURS.Count AS [Hour],
CONCAT(ALLHOURS.Count, ':00') AS [DisplayHour],
ITEM_SUMMARY.OrderModeName,
COALESCE(ITEM_SUMMARY.Sales_Total, 0) AS [Sales],
COALESCE(ITEM_SUMMARY.Comps, 0) AS Comps,
COALESCE(ITEM_SUMMARY.Promos, 0) AS Promos
from ALLHOURS
LEFT OUTER JOIN ITEM_SUMMARY
on ITEM_SUMMARY.DOB = ALLHOURS.DOB
and ITEM_SUMMARY.Hour = ALLHOURS.Hour

Compare dates between rows from the same input file based on ID and replicate rows by increment date till the last working date using SQL Server

I am trying to duplicate rows by comparing the date of the current row with date of the next row for a user ID and row should be duplicated by incrementing the date where < date of the next row.
The last row of the id should increment till the lastworkingdate. If the lastworkingdate is null, should increment the date till current date.
Input:
Output expected
Please suggest if we can implement this logic using SQL Server.
I have tried the below code
WITH cte (User_ID, Start_DateMonth, Start_DateDAY, Last_working_date_text, lead_start_datemonth) AS
(SELECT User_ID,
CONVERT(date, CAST(Start_DateMonth AS varchar(50)) + '01') AS Start_DateMonth,
Start_DateDAY,
Last_working_date_text,
LEAD(CONVERT(datetime, CAST(Start_DateMonth AS varchar(MAX)) + '01')) OVER (PARTITION BY User_ID
ORDER BY CONVERT(date, CAST(Start_DateMonth AS varchar(50)) + '01')) AS lead_start_datemonth
FROM [dbo].[Historic_Headcount3] --mytable
UNION ALL
SELECT User_ID,
CONVERT(date, DATEADD(MONTH, 1, ISNULL(Start_DateMonth, GETDATE()))),
Start_DateDAY,
Last_working_date_text,
CONVERT(datetime, CAST(lead_start_datemonth AS varchar(MAX)) + '01') AS lead_start_datemonth
FROM cte
WHERE DATEADD(MONTH, 1, Start_DateMonth) < ISNULL(lead_start_datemonth,
CASE
WHEN ISDATE(Last_working_date_text) = 1
AND Last_working_date_text != '#' THEN CONVERT(date, Last_working_date_text)
ELSE GETDATE()
END))
SELECT User_ID,
Start_DateMonth,
Start_DateDAY,
Last_working_date_text
FROM cte
ORDER BY User_ID,
Start_DateMonth;
I am getting error
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
This script will hopefully give you enough understanding of how to utilise a numbers table to increment your months, so that you can apply it once you get your data cleaning and transformation working as required:
-- Define test data
declare #t table(UserID int, StartDate date, EndDate date);
insert into #t values(1,'20190901','20200217'),(2,'20200202','20200205'),(3,'20200108',null);
-- Find maximum possible number of Month interations required
declare #Months int = (select datediff(month,min(StartDate),getdate())+1 from #t);
-- Query the data
with t(t) as(select t from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t(t)) -- Create a table with 10 rows in
,n(n) as(select top(#Months) row_number() over (order by (select null))-1 from t t1,t t2,t t3,t t4) -- Cross Join the table to itself to return a row_number() up to a possible 10*10*10*10 = 10,000 rows. Use TOP to limit this to what is actually required.
select t.UserID
,dateadd(month,n.n,t.StartDate) as StartDateMonth
,isnull(t.EndDate,getdate()) as EndDate
from #t as t
join n
on dateadd(month,n.n,t.StartDate) <= isnull(t.EndDate,getdate()) -- JOIN the dates to the row_number, incrementing the months as required
order by UserID
,StartDateMonth;
Output:
+--------+----------------+------------+
| UserID | StartDateMonth | EndDate |
+--------+----------------+------------+
| 1 | 2019-09-01 | 2020-02-17 |
| 1 | 2019-10-01 | 2020-02-17 |
| 1 | 2019-11-01 | 2020-02-17 |
| 1 | 2019-12-01 | 2020-02-17 |
| 1 | 2020-01-01 | 2020-02-17 |
| 1 | 2020-02-01 | 2020-02-17 |
| 2 | 2020-02-02 | 2020-02-05 |
| 3 | 2020-01-08 | 2020-02-26 |
| 3 | 2020-02-08 | 2020-02-26 |
+--------+----------------+------------+
The code worked for me
with cte ([CountryId],[Is_EO_EmployeeId],[DepartmentId],[FunctionId],[Employee_StatusId],[Event_ReasonId],User_ID, Start_DateMonth, Start_DateDAY, Last_working_date_text, lead_start_datemonth) as (
SELECT [CountryId],[Is_EO_EmployeeId],[DepartmentId],[FunctionId],[Employee_StatusId],[Event_ReasonId], User_ID, Start_DateMonth,Start_DateDAY,Last_working_date_text, CASE WHEN lead_start_datemonth IS NULL THEN NULL ELSE Convert(datetime, CAST(lead_start_datemonth AS Nvarchar(max))+'01')END AS lead_start_datemonth FROM (
select
[CountryId],
[Is_EO_EmployeeId],
[DepartmentId],
[FunctionId],
[Employee_StatusId],
[Event_ReasonId],
User_ID,
CONVERT(datetime, CAST(Start_DateMonth AS varchar(50)) + '01') AS Start_DateMonth,
Start_DateDAY,
Last_working_date_text,
lead(Start_DateMonth) over(partition by User_ID order by CONVERT(datetime, CAST(Start_DateMonth AS varchar(50)) + '01')) lead_start_datemonth
from [dbo].[Historic_Headcount3]) T--mytable
union all
select
[CountryId],
[Is_EO_EmployeeId],
[DepartmentId],
[FunctionId],
[Employee_StatusId],
[Event_ReasonId],
User_ID,
Convert(datetime,DateAdd(month,1, ISNULL(Start_DateMonth,GetDate()))),
Start_DateDAY,
Last_working_date_text,
lead_start_datemonth
from cte
where DateAdd(month,1, Start_DateMonth) < ISNULL(lead_start_datemonth,CASE WHEN ISDATE(Last_working_date_text)=1 AND Last_working_date_text != '#' THEN CONVERT(datetime,Last_working_date_text) ELSE GETDATE() END)
)
select [CountryId],[Is_EO_EmployeeId],[DepartmentId],[FunctionId],[Employee_StatusId],[Event_ReasonId],User_ID, LEFT(CONVERT(varchar, Start_DateMonth,112),6) AS Start_DateMonth, Start_DateDAY ,Last_working_date_text from cte order by User_ID, Start_DateMonth OPTion (maxrecursion 0)

SQL Server - Display the number of active sessions for each minute in a time frame

I have the below table:
SessionID | UserName | Started | Ended
----------------------------------------------------------------
100 Test1 2015-07-26 00:03:05 2015-07-26 00:08:12
As the title says, I need to extract between a given #FromDate and a #ToDate parameters, for each minute, how many active sessions were. What I have tried so far does not select the non-active session (when no customers were online in that minute) and I cannot figure it out how to do this.
My SQL Statement
CREATE PROCEDURE [dbo].[ActiveSessionsByMinute] #FromDate datetime, #ToDate datetime
AS
BEGIN
SET NOCOUNT ON
SELECT DATEADD(MINUTE, DATEPART(MINUTE, Started), CAST(CONVERT(varchar(20), Started, 112) AS datetime)) AS DateMinute,
COUNT(SessionID) AS ActiveSessions
FROM ApplicationSessionHistory
GROUP BY DATEADD(MINUTE, DATEPART(MINUTE, Started), CAST(CONVERT(varchar(20), Started, 112) AS datetime))
END
GO
Output
DateMinute | ActiveSessions
-----------------------------------------
2015-07-26 00:03:00.000 | 1
If I execute the below statement, I should get the desired output (below):
EXEC dbo.ActiveSessionsByMinute
#FromDate = '2015-07-26 00:00',
#ToDate = '2015-07-26 00:10'
Desired Output
DateMinute | ActiveSessions
-----------------------------------------
2015-07-26 00:00:00.000 | 0
2015-07-26 00:01:00.000 | 0
2015-07-26 00:02:00.000 | 0
2015-07-26 00:03:00.000 | 1
2015-07-26 00:04:00.000 | 1
2015-07-26 00:05:00.000 | 1
2015-07-26 00:06:00.000 | 1
2015-07-26 00:07:00.000 | 1
2015-07-26 00:08:00.000 | 1
2015-07-26 00:09:00.000 | 0
2015-07-26 00:00:00.000 | 0
Does anyone can give me a tip? Thanks
I would do this with a CTE tally table. Notice I added an extra Session in the sample data.
HERE IS A DEMO
--Sample data
declare #table table (SessionID int, UserName varchar(16), Started datetime, Ended datetime)
insert into #table
values
(100,'Test1','2015-07-26 00:03:05','2015-07-26 00:08:12')
,(101,'Test1','2015-07-26 00:04:05','2015-07-26 00:05:12')
--used as a beginning anchor for the tally table
declare #startDate datetime = (select min(cast(Started as date)) from #table)
--take the original data, and truncate the seconds
;with NewTable as(
select
SessionID
,UserName
,Started = CAST(DateAdd(minute, DateDiff(minute, 0, Started), 0) AS smalldatetime)
,Ended = CAST(DateAdd(minute, DateDiff(minute, 0, Ended), 0) AS smalldatetime)
from #table
),
--tally table to get 10K minutes.
--This can be expanded for larger date ranges, and is faster than recursive CTE
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT TallyDate = dateadd(minute,ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),#startDate) FROM E4
)
--use cross apply and and a case statement to find if it falls in the range
select
DateMinute = N
,SessionID
,Started
,Ended
,IsActive = case when (Started <=N and Ended >= N) then 1 else 0 end
from NewTable t
cross apply cteTally
where N <= (select max(Ended) from #table)
order by SessionID, N
For the sum part, you can simply aggregate. Replace the last SELECT with this one
--based on the above output, just do the SUM
select
DateMinute = N
,ActiveSessions = sum(case when (Started <=N and Ended >= N) then 1 else 0 end)
from NewTable t
cross apply cteTally
where N <= (select max(dateadd(minute,1,Ended)) from #table)
group by N
order by N
You'll want to SELECT from a tally table with all the minutes and LEFT JOIN to your ApplicationSessionHistory table:
CREATE PROCEDURE [dbo].[ActiveSessionsByMinute]
#FromDate DATETIME
, #ToDate DATETIME
AS
BEGIN
SET NOCOUNT ON;
SELECT allminutes.alltimes AS DateMinute
, COUNT(SessionID) AS ActiveSessions
FROM
(
SELECT DATEADD(MINUTE, myrows.rn, #FromDate) AS alltimes
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY s.id) - 1 rn
FROM master.sys.syscolumns AS s
) myrows
) allminutes
LEFT OUTER JOIN ApplicationSessionHistory ON allminutes.alltimes BETWEEN ApplicationSessionHistory.Started AND ApplicationSessionHistory.Ended
WHERE allminutes.alltimes <= #ToDate
GROUP BY DATEADD(MINUTE, DATEPART(MINUTE, Started), CAST(CONVERT(VARCHAR(20), Started, 112) AS DATETIME));
END;

Return the current month salary and previous month salary in a same table

I have a task to prepare a report generated from a run control page and retrieve the current month salary and previous month salary. In that page, the user will choose the cal_id they want for example in this case the user choose cal id = FEB. Assume the table as below named table_salary:
emplid | cal_id | salary | pymt_date
101 | JAN | 10000 | 2018-01-01
101 | FEB | 15000 | 2018-02-01
And my expected output is
emplid | cur_sal| prev_sal
101 | 15000 | 10000
What I have done so far is like below
SELECT
A.EMPLID, A.SALARY AS CUR_SAL, B.SALARY AS PREV_SAL
FROM
TABLE_SALARY A
LEFT OUTER JOIN
TABLE_SALARY B ON A.EMPLID AND B.EMPLID
AND A.CAL_ID = B.CAL_ID
AND B.PYMT_DT = (SELECT MAX(B1.PYMT_DT)
FROM TABLE_SALARY B1
WHERE B1.EMPLID = B.EMPLID
AND B1.PYMT_DT >= DATEADD(mm, DATEDIFF(mm, 0, B.PYMT_DT) - 1, 0)
AND B1.PYMT_DT < DATEADD(mm, DATEDIFF(mm, 0, PYMT_DT), 0))
But above SQL didn't return the expected output.
Does anyone have an idea how to achieve my expected output?
It should be like this
Use Lead instead of Lag
Create table #t ( id int identity (1,1), Empid int , Month varchar
(10), Salary int, Paymentdate date )
insert into #t (Empid ,Month,Salary,Paymentdate) Select
'1','Jan',1000, '2018-01-01'
insert into #t (Empid ,Month,Salary,Paymentdate) Select
'1','Feb',1500, '2018-02-01'
Select * from #t
SELECT TOP 1
Empid, SALARY AS CUR_SAL, Lead(SALARY, 1, 0) OVER (ORDER BY PaymentDate DESC) AS PREV_SAL FROM
#t ORDER BY
Paymentdate DESC
SELECT TOP 1
Empid, SALARY AS CUR_SAL, LAG(SALARY, 1, 0) OVER (ORDER BY PaymentDate DESC) AS PREV_SAL FROM
#t ORDER BY
Paymentdate DESC
Use a window function to retrieve the previous row in a sorted set. I think this should work.
SELECT TOP 1
EMPLID, SALARY AS CUR_SAL, LEAD(SALARY, 1, 0) OVER (ORDER BY PYMT_DT DESC) AS PREV_SAL
FROM
TABLE_SALARY
ORDER BY
PYMT_DT DESC

Resources