Here is the sample data from the employee vacation table.
Emp_id Vacation_Start_Date Vacation_End_Date Public_Hday
1234 06/01/2022 06/07/2022 null
1234 06/08/2022 06/14/2022 null
1234 06/15/2022 06/19/2022 06/17/2022
1234 06/20/2022 06/23/2022 null
1234 06/24/2022 06/28/2022 null
1234 06/29/2022 07/02/2022 06/30/2022
1234 07/03/2022 07/07/2022 null
1234 07/08/2022 07/12/2022 null
1234 07/13/2022 07/17/2022 07/15/2022
1234 07/18/2022 07/22/2022 null
I want to group these vacations based on the public holidays in between (Assuming that all the vacations are consecutive). Here is the output that I am trying to get.
Emp_id Vacation_Start_Date Vacation_End_Date Public_Hday Group
1234 06/01/2022 06/07/2022 null 0
1234 06/08/2022 06/14/2022 null 0
1234 06/15/2022 06/19/2022 06/17/2022 1
1234 06/20/2022 06/23/2022 null 1
1234 06/24/2022 06/28/2022 null 1
1234 06/29/2022 07/02/2022 06/30/2022 2
1234 07/03/2022 07/07/2022 null 2
1234 07/08/2022 07/12/2022 null 2
1234 07/13/2022 07/17/2022 07/15/2022 3
1234 07/18/2022 07/22/2022 null 3
Here is the code that I tried
Select *, dense_rank() over (partition by Emp_id order by Public_Hday) - 1 AS Group from Emp_Vacation.
But, it gave the expected group values only to the vacations where the Public_Hday is not null. How do I get the group values to the other vacations.
You can use a conditional sum() over()
Select *
,Grp = sum( case when [Public_Hday] is null then 0 else 1 end ) over (partition by [Emp_id] order by [Vacation_Start_Date])
from YourTable
Results
I have this query:
SELECT DISTINCT
MAX(D.RECEIVEDDATE) AS DATE,
A.LOCATIONNUMBER AS ID_NAME,
(SELECT CARRIERNUMBER FROM CARRIER C WHERE C.CARRIERID = D.CARRIERID) AS CR_NAME,
D.DEPOSITREFERENCE As ITEM_REF,
DC.CONTAINERNUMBER As ITEM_NUM,
Z.DENOMINATION As Category,
D.RECEIVEDCONTAINERS as ITEM_QTY,
SUM(CASE WHEN Z.DENOMINATION LIKE '%50%' THEN CAST(Z.VERIFIEDQUANTITY AS BIGINT) END) QTY_50_PCS,
SUM(CASE WHEN Z.DENOMINATION LIKE '%100%' THEN CAST(Z.VERIFIEDQUANTITY AS BIGINT) END) QTY_100_PCS,
SUM(CASE WHEN Z.DENOMINATION LIKE '%50%' THEN CAST(Z.VERIFIEDAMOUNT AS BIGINT) END) AMT_50_PCS,
SUM(CASE WHEN Z.DENOMINATION LIKE '%100%' THEN CAST(Z.VERIFIEDAMOUNT AS BIGINT) END) AMT_100_PCS,
CAST(D.VERIFIEDAMOUNT AS BIGINT) AS TOTAL_AMT
FROM
DEPOSIT D
JOIN
ACCOUNT A ON D.ACCOUNTID = A.ACCOUNTID
LEFT JOIN
DEPOSITCONTAINER DC ON DC.DEPOSITID = D.DEPOSITID
LEFT JOIN
DEPOSITCONTAINERITEM Z ON Z.DEPOSITCONTAINERID = DC.DEPOSITCONTAINERID
LEFT JOIN
DEPOSITCONTAINERITEMUNIT X ON X.DEPOSITCONTAINERITEMID = Z.DEPOSITCONTAINERITEMID
WHERE
D.DEPOSITTYPE = 0
AND LOCATIONNUMBER LIKE 'Z%'
AND D.RECEIVEDDATE IS NOT NULL
AND Z.DENOMINATION IS NOT NULL
GROUP BY
D.RECEIVEDDATE, A.LOCATIONNUMBER, D.CARRIERID, D.DEPOSITREFERENCE,
D.RECEIVEDCONTAINERS, D.VERIFIEDAMOUNT, DC.CONTAINERNUMBER, DC.VERIFIEDAMOUNT, Z.DENOMINATION
ORDER BY
D.DEPOSITREFERENCE
The output/result will become like this:
DATE
ID_NAME
CR_NAME
ITEM_REF
ITEM_NUM
CATEGORY
ITEM_QTY
QTY_50_PCS
QTY_100_PCS
AMT_50_PCS
AMT_100_PCS
TOTAL_AMT
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-050-210001
50000
6
2000
NULL
100000000
NULL
672600000
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-050-210002
50000
6
2095
NULL
104750000
NULL
672600000
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-100-2100002
100000
6
NULL
2120
NULL
212000000
672600000
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-100-210001
100000
6
NULL
2069
NULL
206900000
672600000
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-RJC-210001
100000
6
NULL
383
NULL
38300000
672600000
2021-07-26
XXN8A
ABC
0039546898202ZZN8A
N5-RJC-210001
50000
6
213
NULL
10650000
NULL
672600000
2021-07-27
CCY57
CAB
0344416011204ZZY57
G6-50-210153
50000
6
68
NULL
3400000
NULL
140050000
2021-07-27
CCY57
CAB
0344416011204ZZY57
G6-50-210154
50000
6
75
NULL
3750000
NULL
140050000
2021-07-27
CCY57
CAB
0344416011204ZZY57
G6-RJC-210153
100000
6
NULL
486
NULL
48600000
140050000
2021-07-27
CCY57
CAB
0344416011204ZZY57
G6-RJC-210153
50000
6
26
NULL
1300000
NULL
140050000
How to get the transpose table with only one row and the columns based on the ITEM_NUM? For example, the 1st item N5-050-210001 with value quantity of 2000 will be in the QTY_50 column, then if there's second item N5-050-210002 with value 2095, it will be placed in second column QTY_50_2. This is also applied to the ITEM_NUM like '%-100-%' and '%-RJC%', the ITEM_NUM and Category columns will be eliminated and the result I want is to be like this:
DATE
ID_NAME
CR_NAME
ITEM_REF
ITEM_QTY
QTY_50
QTY_50_2
QTC_RJC_50
QTY_100
QTY_100_2
QTC_RJC_100
AMT_50_PCS
AMT_100_PCS
TOTAL_AMT
7/26/2021
XXN8A
ABC
0039546898202ZZN8A
6
2000
2095
213
2069
2120
383
215400000
457200000
672600000
7/27/2021
CCY57
CAB
0344416011204ZZY57
6
68
75
26
773
57
486
8450000
131600000
140050000
Any suggestion?
If you want a result set that has a single row for each combination of DATE, ID_NAME, CR_NAME, and ITEM_REF, then these should be the only columns in the GROUP BY. However, DATE is really an aggregation expression, so you only want the other three.
So:
SELECT MAX(RECEIVEDDATE) as DATE, ID_NAME, CR_NAME, ITEM_REF,
SUM(CASE WHEN Z.DENOMINATION LIKE '%50%' THEN CAST(Z.VERIFIEDQUANTITY AS BIGINT) END) as QTY_50_PCS,
. .
FROM . . .
GROUP BY ID_NAME, CR_NAME, ITEM_REF;
I have a table as follows:
Order_ID
Ship_num
Item_code
Qty_to_pick
Qty_picked
Pick_date
1111
1
1
3000
0
Null
1111
1
2
2995
1965
2021-05-12
1111
2
1
3000
3000
2021-06-24
1111
2
2
1030
0
Null
1111
3
2
1030
1030
2021-08-23
2222
1
3
270
62
2021-03-18
2222
1
4
432
0
Null
2222
2
3
208
0
Null
2222
2
4
432
200
2021-05-21
2222
3
3
208
208
2021-08-23
2222
3
4
232
200
2021-08-25
From this table,
I only want to show the rows that has the latest ship_num information, not the latest pick_date information (I was directed to a question like this that needed to return the rows with the latest entry time, I am not looking for that) for an order i.e., I want it as follows
Order_ID
Ship_num
Item_code
Qty_to_pick
Qty_picked
Pick_date
1111
3
2
1030
1030
2021-08-23
2222
3
3
208
208
2021-08-23
2222
3
4
232
200
2021-08-25
I tried the following query,
select order_id, max(ship_num), item_code, qty_to_pick, qty_picked, pick_date
from table1
group by order_id, item_code, qty_to_pick, qty_picked, pick_date
Any help would be appreciated.
Thanks in advance.
Using max(ship_num) is a good idea, but you should use the analytic version (with an OVER clause).
select *
from
(
select t.*, max(ship_num) over (partition by order_id) as orders_max_ship_num
from table1 t1
) with_max
where ship_num = orders_max_ship_num
order by order_id, item_code;
You can get this using the DENSE_RANK().
Query
;with cte as (
select rnk = dense_rank()
over (Partition by order_id order by ship_num desc)
, *
from table_name
)
Select *
from cte
Where rnk =1;
I am joining two tables based on a common column date. However, the column I am trying to get from one the table (cmg) in this case, should get next row value only if it is different from its previous row's value
Table A
Date comp.no
-----------------------
2019-03-08 5
2019-02-26 5
2019-01-17 5
2019-01-10 5
2018-12-27 5
Table B
Date cmg
-----------------
2019-07-17 NULL
2019-04-20 NULL
2019-02-26 RHB
2019-01-19 NULL
2019-01-17 RHB
2019-01-10 RMB
2018-12-28 NULL
2018-12-27 RHB
2018-12-12 RUB
2018-11-28 RUB
2018-10-20 NULL
2018-07-21 NULL
2018-04-21 NULL
2018-01-20 NULL
2017-10-21 NULL
2017-07-29 NULL
2017-05-07 NULL
2017-02-13 NULL
2016-11-22 NULL
2016-08-29 NULL
2016-06-07 NULL
2016-04-06 RUB
2016-03-21 RUB
2016-03-07 RUB
You can use lag function to compare with previous value. And for the first row you'll need an isnull() check since the first row won't have a previous value.
;with cte as(
select case
when isnull(lag(t2.cmg)over (order by t2.cmg desc),'') <>t2.cmg then 1 else 0 end as isresult
,t2.date,t2.cmg
from TableA t1
inner join TableB t2
on t1.date=t2.date
)
select date,cmg from cte where isresult=1
Use lag():
select date, cmg
from (select b.date, b.cmg, lag(b.cmg) over (order by b.date) as prev_cmg
from a join
b
on a.date = b.date
) b
where prev_cmg is null or prev_cmg <> cmg
order by date;
I want to calculate Opening and Closing Balance of a business application. But for some rows wrong Opening Balance is producing. I have following Data Tables:
SupplierPayments
DateOfPayment Bill
2018-06-01 4000
2018-06-01 9000
2018-06-19 2000
2018-06-19 6000
2019-03-28 3000
2019-03-29 5000
Expensis
DateOfExpense Expense
2018-08-14 2,000
2019-02-26 8,000
2019-03-28 2000
2019-03-29 2000
Income
DateSold Income
2018-09-27 24,000
2018-10-17 8,000
2019-01-01 13,000
2019-03-28 10,000
SQL Server 2012 Query
with Income( DateSold, Income ) as (
select DateSold,isnull(sum(TotalBill),0)
from SalesInvoice group by DateSold
), SupplierPayments( DateOfPayment,Bill ) as(
select DateOfPayment,isnull(sum(BillPaidAmount),0)
from SupplyInvoicePaymentHistory group by DateOfPayment
), Expensis( DateOfExpense, Expense ) as(
select Date ,isnull(sum(Amount),0)
from GeneralExpense group by Date
), t as (
select i.DateSold
,e.DateOfExpense
,sp.DateOfPayment
,i.income
, e.Expense
,sp.Bill
, sum(isnull(i.income,0)-(isnull(e.Expense,0)+isnull(sp.Bill,0))) over (order by i.DateSold,e.DateOfExpense,sp.DateOfPayment) as closing_balance
from income i
full outer join expensis e on e.DateOfExpense = i.DateSold
full outer join SupplierPayments sp on sp.DateOfPayment=e.DateOfExpense
)
select m.EventDate, m.DateSold
,m.DateOfExpense
,m.DateOfPayment
,isnull(m.opening_balance,0) as Opening_Balance
,isnull(m.Income,0) as Income
,isnull(m.Expense,0) as Expensis
,isnull(m.Bill,0) as SupplierPayments
,isnull(m.closing_balance,0) as Closing_Balance
from (
select coalesce(coalesce(DateOfPayment, DateOfExpense), DateSold) EventDate, DateSold
,DateOfExpense
,DateOfPayment
,lag(closing_balance,1,0) over (order by DateSold, DateOfExpense,DateOfPayment) as opening_balance
,Income
,Expense
,closing_balance
,Bill
from t
) as m order by m.EventDate ASC
Output
EventDate DateSold ExpenseDate PaymentDate Opening Income Expense Bill Closing
2018-06-01 NULL NULL 2018-06-01 0 0 0 13000 -13000
2018-06-19 NULL NULL 2018-06-19 -13000 0 0 8000 -21000
2018-08-14 NULL 2018-08-14 NULL -21000 0 2000 0 -23000
2018-09-27 2018-09-27 NULL NULL -30000 24000 0 0 -6000
2019-01-01 2019-01-01 NULL NULL -6000 13000 0 0 7000
2019-03-28 2019-03-28 2019-03-28 2019-03-28 7000 10000 2000 3000 12000
2019-03-29 NULL 2019-03-29 2019-03-29 -23000 0 2000 5000 -30000
Formula to calculate closing balance is as:
Closing = Opening + Income - Expense - Bill
As we can notice that opening balance for date 2018-09-27 is -30,000 which is wrong. It should be -23,000. similarly opening balance for date 2019-03-29 is also wrong.
Required Result
EventDate DateSold ExpenseDate PaymentDate Opening Income Expense Bill Closing
2018-06-01 NULL NULL 2018-06-01 0 0 0 13000 -13000
2018-06-19 NULL NULL 2018-06-19 -13000 0 0 8000 -21000
2018-08-14 NULL 2018-08-14 NULL -21000 0 2000 0 -23000
2018-09-27 2018-09-27 NULL NULL -23000 24000 0 0 1000
2019-01-01 2019-01-01 NULL NULL 1000 13000 0 0 14000
2019-03-28 2019-03-28 2019-03-28 2019-03-28 14000 10000 2000 3000 19000
2019-03-29 NULL 2019-03-29 2019-03-29 19000 0 2000 5000 12000
It is possible that in any day there is No item sold but there is expense or bill paid to supplier and vice versa.
Also it is possible that any tables has two entries on the same date.
Your issue lies within the order by columns for both SUM and LAG. If you selected from t CTE alone, you'd see that you're not ordering by whatever is in any of the three dates (what's available), you're ordering by them in the order you specified. So you'll get NULLs for the first column first, NULLs for the second column first, etc. What you need to do is introduce the EventDate sooner, in t, and order everything by it.
;with xIncome( DateSold, Income ) as (
select DateSold,isnull(sum(income),0)
from income group by DateSold
), xSupplierPayments( DateOfPayment,Bill ) as(
select DateOfPayment,isnull(sum(bill),0)
from supplierpayments group by DateOfPayment
), xExpensis( DateOfExpense, Expense ) as(
select DateOfExpense Date ,isnull(sum(expense),0)
from expensis group by Dateofexpense
), t as (
select i.DateSold
,e.DateOfExpense
,sp.DateOfPayment
,consolidated.date consolidatedDate
,i.income
, e.Expense
,sp.Bill
, sum(isnull(i.income,0)-(isnull(e.Expense,0)+isnull(sp.Bill,0))) over (order by consolidated.date) as closing_balance
from xincome i
full outer join xexpensis e on e.DateOfExpense = i.DateSold
full outer join xSupplierPayments sp on sp.DateOfPayment=e.DateOfExpense
cross apply (select coalesce(i.DateSold,e.DateOfExpense,sp.DateOfPayment) as date) consolidated
)
select consolidatedDate, m.DateSold
,m.DateOfExpense
,m.DateOfPayment
,isnull(m.opening_balance,0) as Opening_Balance
,isnull(m.Income,0) as Income
,isnull(m.Expense,0) as Expensis
,isnull(m.Bill,0) as SupplierPayments
,isnull(m.closing_balance,0) as Closing_Balance
from (
select consolidatedDate
,DateSold
,DateOfExpense
,DateOfPayment
,lag(closing_balance,1,0) over (order by consolidatedDate) as opening_balance
,Income
,Expense
,closing_balance
,Bill
from t
) as m order by m.consolidatedDate ASC
Notice the CROSS APPLY in t CTE, where I COALESCE all the dates into a single cosnolidated date. I had to rename the first CTEs to match your sample data table names, but you get the gist of it.