Differentiate on the basis of date - sql-server

I have this table structure and query written with the help of some guy here and it works perfect but I want to order the rows on the basis of dates.
Here is the structure and sample data:
DROP TABLE [TransactionMaster];
DROP TABLE [VoucherType];
CREATE TABLE [VoucherType](
[VoucherTypeCode] [tinyint] NOT NULL PRIMARY KEY,
[FullName] [nvarchar](255) NOT NULL
);
INSERT INTO [VoucherType] VALUES (1, 'Cash Payment Voucher');
INSERT INTO [VoucherType] VALUES (2, 'Cash Receipt Voucher');
INSERT INTO [VoucherType] VALUES (3, 'Bank Payment Voucher');
INSERT INTO [VoucherType] VALUES (4, 'Bank Receipt Voucher');
CREATE TABLE [TransactionMaster](
[ID] [bigint] NOT NULL PRIMARY KEY,
[VoucherTypeCode] [tinyint] NOT NULL,
[PayeeName] [varchar](255) NOT NULL,
[TransactionDate] datetime,
[RefNo] [nvarchar](50) NULL
CONSTRAINT [FK_tbl_TransactionMaster_tbl_VoucherType] FOREIGN KEY([VoucherTypeCode])
REFERENCES [VoucherType] ([VoucherTypeCode])
)
INSERT INTO [TransactionMaster] VALUES (1, 2, 'Asim', '2018-03-21', 'CRV-0001-LHR');
INSERT INTO [TransactionMaster] VALUES (2, 4, 'Ali', '2018-03-21', 'BRV-2421-KHI');
INSERT INTO [TransactionMaster] VALUES (3, 1, 'Erick', '2018-03-23', 'CPV-5435-ISL');
INSERT INTO [TransactionMaster] VALUES (4, 3, 'Asim', '2018-03-24', 'BPV-2345-CAN');
INSERT INTO [TransactionMaster] VALUES (5, 2, 'Mehboob', '2018-03-25', 'CRV-2976-PSH');
INSERT INTO [TransactionMaster] VALUES (6, 1, 'Erick', '2018-03-25', 'CPV-2323-KOH');
Here is the query
SELECT tb1.Refno
,tb1.[FullName] AS VType
,tb1.PayeeName
,tb2.Refno
,tb2.[FullName] AS VType
,tb2.PayeeName
FROM
(
(
SELECT
ROW_NUMBER() OVER ( ORDER BY id ) AS rowid
,TransactionMaster.RefNo
,TransactionMaster.PayeeName
,[VoucherType].FullName
FROM
TransactionMaster
INNER JOIN
[VoucherType]
ON TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
WHERE TransactionMaster.[VoucherTypeCode] IN ( 1,3 )
) tb1
FULL OUTER JOIN
(
SELECT
ROW_NUMBER() OVER ( ORDER BY id ) AS rowid
,TransactionMaster.RefNo
,TransactionMaster.PayeeName
,[VoucherType].FullName
FROM
TransactionMaster
INNER JOIN
[VoucherType]
ON TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
WHERE TransactionMaster.[VoucherTypeCode] IN ( 2,4 )
) tb2 ON tb1.rowid = tb2.rowid
)
The output right now is like this::
Refno VType PayeeName TransactionDate Refno VType PayeeName TransactionDate
CPV-5435-ISL Cash Payment Voucher Erick 2018-03-23 00:00:00.000 CRV-0001-LHR Cash Receipt Voucher Asim 2018-03-21 00:00:00.000
BPV-2345-CAN Bank Payment Voucher Asim 2018-03-24 00:00:00.000 BRV-2421-KHI Bank Receipt Voucher Ali 2018-03-21 00:00:00.000
CPV-2323-KOH Cash Payment Voucher Erick 2018-03-25 00:00:00.000 CRV-2976-PSH Cash Receipt Voucher Mehboob 2018-03-25 00:00:00.000
I want to show the date in ascending order and in case no voucher exist on that date it should be null.
I am putting the expected output below
Refno VType PayeeName TransactionDate Refno VType PayeeName TransactionDate
CRV-0001-LHR Cash Receipt Voucher Asim 2018-03-21 00:00:00.000
BRV-2421-KHI Bank Receipt Voucher Ali 2018-03-21 00:00:00.000
CPV-5435-ISL Cash Payment Voucher Erick 2018-03-23 00:00:00.000
BPV-2345-CAN Bank Payment Voucher Asim 2018-03-24 00:00:00.000
CPV-2323-KOH Cash Payment Voucher Erick 2018-03-25 00:00:00.000 CRV-2976-PSH Cash Receipt Voucher Mehboob 2018-03-25 00:00:00.000

You can use COALESCE to concat your dates and then order by it. Hopefully this would resolve your question
with data1 as (
select a.id,a.VoucherTypeCode,PayeeName,TransactionDate,RefNo,FullName from TransactionMaster a inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
where a.VoucherTypeCode in (1,3)
),
data2 as (
select a.id,a.VoucherTypeCode,PayeeName,TransactionDate,RefNo,FullName from TransactionMaster a inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
where a.VoucherTypeCode in (2,4)
)
select *,COALESCE(a.TransactionDate,b.TransactionDate) as FullDate from data1 a full join data2 b on a.TransactionDate = b.TransactionDate
order by FullDate
Result

Try this
select tb1.Refno,
tb1.[FullName] as VType,
tb1.PayeeName,
tb2.Refno,
tb2.[FullName] as VType,
tb2.PayeeName
from(
(
select ROW_NUMBER()over (partition by TransactionDate order by id) as rowid,
TransactionMaster.RefNo,
TransactionMaster.PayeeName,
[VoucherType].FullName,
TransactionMaster.TransactionDate
from TransactionMaster
inner join [VoucherType] on TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
where TransactionMaster.[VoucherTypeCode] in (1,3)
)tb1
full outer join (
select ROW_NUMBER()over (partition by TransactionDate order by id) as rowid,
TransactionMaster.RefNo,
TransactionMaster.PayeeName,
[VoucherType].FullName,
TransactionMaster.TransactionDate
from TransactionMaster
inner join [VoucherType] on TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
where TransactionMaster.[VoucherTypeCode] in (2,4)
) tb2 on tb1.rowid = tb2.rowid and tb1.TransactionDate = tb2.TransactionDate
)

Related

Repeated data on inserted rows

--demo setup
drop table if exists dbo.product
go
create table dbo.Product
(
ProductId int,
ProductTitle varchar(55),
ProductCategory varchar(255),
Loaddate datetime
)
insert into dbo.Product
values (1, 'Table', 'ABCD', '3/4/2018'),
(1, 'Table', 'ABCD', '3/5/2018'),
(1, 'Table', 'ABCD', '3/6/2018'),
(1, 'Table', 'XYZ', '3/7/2018'),
(1, 'Table', 'XYZ', '3/8/2018'),
(1, 'Table', 'XYZ', '3/9/2018'),
(1, 'Table', 'GHI', '3/10/2018'),
(1, 'Table', 'GHI', '3/11/2018'),
(1, 'Table', 'XYZ', '3/12/2018'),
(1, 'Table', 'XYZ', '3/13/2018')
SELECT
product.productid,
product.producttitle,
product.productcategory,
MIN(product.loaddate) AS BeginDate,
-- ,max(product.LoadDate) as BeginDate1
CASE
WHEN MAX(product.loaddate) = MAX(oa.enddate1)
THEN '12/31/9999'
ELSE MAX(product.loaddate)
END AS EndDate
FROM
dbo.product product
CROSS APPLY
(SELECT MAX(subproduct.loaddate) EndDate1
FROM dbo.product subproduct
WHERE subproduct.productid = product.productid) oa
GROUP BY
productid, producttitle, productcategory
Output:
productid
producttitle
productcategory
BeginDate
EndDate
1
Table
ABCD
2018-03-04 00:00:00.000
2018-03-06 00:00:00.000
1
Table
XYZ
2018-03-07 00:00:00.000
9999-12-31 00:00:00.000
1
Table
GHI
2018-03-10 00:00:00.000
2018-03-11 00:00:00.000
Desired output:
productid
producttitle
productcategory
BeginDate
EndDate
1
Table
ABCD
2018-03-04 00:00:00.000
2018-03-06 00:00:00.000
1
Table
XYZ
2018-03-07 00:00:00.000
2018-03-09 00:00:00.000
1
Table
GHI
2018-03-10 00:00:00.000
2018-03-11 00:00:00.000
1
Table
XYZ
2018-03-12 00:00:00.000
9999-12-31 00:00:00.000
The last two inserted rows repeat the data from Loaddate '3/7/2018'-'3/9/2018', this doesn't happen if any of the new inserted rows doesn't repeat data. The only thing that changes is the LoadDate, giving me incorrect output. how can i get something like that desired output?
Well, first of all, you need to find a sequence number over all your records. If you already have a primary key, that's good. In example you gave us, there's no such column, so let's generate it.
Then, we make pairs with start and end dates for each product's category change. Another thing is to group all these product's category changes.
Finally, we make just a simple group by:
;
with cte as ( select *,
row_number() over(partition by ProductId order by Loaddate) as rn
from product
), cte2 as ( select t1.ProductId,
t1.ProductTitle,
t1.ProductCategory,
t1.Loaddate as BeginDate,
case
when t1.ProductCategory <> t2.ProductCategory
then t1.Loaddate
else coalesce(t2.Loaddate, null)
end as EndDate,
row_number() over(order by t1.ProductId, t1.Loaddate) as rn_overall,
row_number() over(partition by t1.ProductId, t1.ProductCategory order by t1.Loaddate) as rn_category
from cte as t1
left join cte as t2
on t2.ProductId = t1.ProductId
and t2.rn = t1.rn + 1
), cte3 as ( select *,
min(rn_overall) over (partition by ProductId, ProductCategory, rn_overall - rn_category) as product_group
from cte2
)
select ProductId, ProductTitle, ProductCategory,
min(BeginDate) as BeginDate,
case
when max(case when EndDate is null then 1 else 0 end) = 0
then max(EndDate)
else null
end as EndDate
from cte3
group by ProductId, ProductTitle, ProductCategory, product_group
order by ProductId, BeginDate

Opening and Closing Balance is wrt Debit and Credit amount

I have this table structure and query written with the help of some guy here and it works perfect. I want to get the opening and closing balance between the dates. I have commented the date on which I want to get the date and if I run that date check the expected output I want is shown below.
Here is the structure and sample data:
DROP TABLE [TransactionMaster];
DROP TABLE [VoucherType];
CREATE TABLE [VoucherType](
[VoucherTypeCode] [tinyint] NOT NULL PRIMARY KEY,
[FullName] [nvarchar](255) NOT NULL
);
INSERT INTO [VoucherType] VALUES (1, 'Cash Payment Voucher');
INSERT INTO [VoucherType] VALUES (2, 'Cash Receipt Voucher');
INSERT INTO [VoucherType] VALUES (3, 'Bank Payment Voucher');
INSERT INTO [VoucherType] VALUES (4, 'Bank Receipt Voucher');
CREATE TABLE [TransactionMaster](
[ID] [bigint] NOT NULL PRIMARY KEY,
[VoucherTypeCode] [tinyint] NOT NULL,
[PayeeName] [varchar](255) NOT NULL,
[TransactionDate] datetime,
[RefNo] [nvarchar](50) NULL
CONSTRAINT [FK_tbl_TransactionMaster_tbl_VoucherType] FOREIGN KEY([VoucherTypeCode])
REFERENCES [VoucherType] ([VoucherTypeCode])
)
INSERT INTO [TransactionMaster] VALUES (1, 2, 'Asim', '2018-03-21', 'CRV-0001-LHR');
INSERT INTO [TransactionMaster] VALUES (2, 4, 'Ali', '2018-03-21', 'BRV-2421-KHI');
INSERT INTO [TransactionMaster] VALUES (3, 1, 'Erick', '2018-03-23', 'CPV-5435-ISL');
INSERT INTO [TransactionMaster] VALUES (4, 3, 'Asim', '2018-03-24', 'BPV-2345-CAN');
INSERT INTO [TransactionMaster] VALUES (5, 2, 'Mehboob', '2018-03-25', 'CRV-2976-PSH');
INSERT INTO [TransactionMaster] VALUES (6, 1, 'Erick', '2018-03-25', 'CPV-2323-KOH');
INSERT INTO [TransactionMaster] VALUES (7, 1, 'Feroze', '2018-03-21', 'CRV-0531-SRG');
INSERT INTO [TransactionMaster] VALUES (8, 3, 'Ali', '2018-03-21', 'BRV-2001-RWP');
CREATE TABLE TransactionDetail
(
ID NUMERIC NOT NULL PRIMARY KEY,
TransactionCode bigint,
DrAmount NUMERIC,
CrAmount NUMERIC
);
INSERT INTO TransactionDetail VALUES (1, 1, '2500', NULL);
INSERT INTO TransactionDetail VALUES (2, 1, NULL, '1500');
INSERT INTO TransactionDetail VALUES (3, 1, NULL, '1000');
INSERT INTO TransactionDetail VALUES (4, 2, '1150', NULL);
INSERT INTO TransactionDetail VALUES (5, 2, NULL, '1150');
INSERT INTO TransactionDetail VALUES (6, 3, '600', NULL);
INSERT INTO TransactionDetail VALUES (7, 3, '400', NULL);
INSERT INTO TransactionDetail VALUES (8, 3, '200', NULL);
INSERT INTO TransactionDetail VALUES (9, 3, NULL, '1200');
INSERT INTO TransactionDetail VALUES (10, 4, '1000', NULL);
INSERT INTO TransactionDetail VALUES (11, 4, NULL, '1000');
INSERT INTO TransactionDetail VALUES (12, 5, '2400', NULL);
INSERT INTO TransactionDetail VALUES (13, 5, NULL, '1200');
INSERT INTO TransactionDetail VALUES (14, 5, NULL, '1000');
INSERT INTO TransactionDetail VALUES (15, 5, NULL, '200');
INSERT INTO TransactionDetail VALUES (16, 6, '2900', NULL);
INSERT INTO TransactionDetail VALUES (17, 6, NULL, '2900');
INSERT INTO TransactionDetail VALUES (18, 7, '700', NULL);
INSERT INTO TransactionDetail VALUES (19, 7, '300', NULL);
INSERT INTO TransactionDetail VALUES (20, 7, '2100', NULL);
INSERT INTO TransactionDetail VALUES (21, 7, NULL, '3100');
INSERT INTO TransactionDetail VALUES (22, 8, '500', NULL);
INSERT INTO TransactionDetail VALUES (23, 8, NULL, '500');
Here is the query
with data1 as (
select a.id inid,a.VoucherTypeCode,PayeeName,MAX(c.DrAmount) InAmount,TransactionDate,RefNo,FullName from TransactionMaster a
inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
inner join TransactionDetail c on a.ID = c.TransactionCode
where a.VoucherTypeCode in (1,3)
GROUP BY a.id,a.VoucherTypeCode,PayeeName,TransactionDate,RefNo,FullName
),
data2 as (
select a.id outid,a.VoucherTypeCode,PayeeName,MAX(c.CrAmount) OutAmount,TransactionDate,RefNo,FullName from TransactionMaster a
inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
inner join TransactionDetail c on a.ID = c.TransactionCode
where a.VoucherTypeCode in (2,4)
GROUP BY a.id,a.VoucherTypeCode,PayeeName,TransactionDate,RefNo,FullName
)
select *,COALESCE(a.TransactionDate,b.TransactionDate) as FullDate from data1 a full join data2 b on inid = outid and a.TransactionDate = b.TransactionDate
--WHERE COALESCE(a.TransactionDate,b.TransactionDate) BETWEEN '2018-03-23 00:00:00.000' AND '2018-03-24 00:00:00.000'
order by FullDate
The expected output is provided below when you remove the commenting from the date check:
inid VoucherTypeCode PayeeName InAmount TransactionDate RefNo FullName outid VoucherTypeCode PayeeName OutAmount TransactionDate RefNo FullName FullDate Opening
-------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------
3 1 Erick 1200 2018-03-23 00:00:00.000 CPV-5435-ISL Cash Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-23 00:00:00.000 -50
4 3 Asim 1000 2018-03-24 00:00:00.000 BPV-2345-CAN Bank Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-24 00:00:00.000 1150
The formula is that (Opening+InAmount) - Out Amount will be the Closing Balance and Opening will be previous rows Closing Balance.
So for first record opening will be 0 and closing will be 3100 and for second opening = 3100 and closing 3600 and so on.
If the VoucherType is 1 or 3 than I have to get the Credit Amount CrAmount and if the VoucherType is 2 or 4 then I need to get the Debit Amount DrAmount.
I've asked this question before and got the expected output as well but now the DB structure is changed a bit and I am unable to use that logic here.
basically it is the same as the previous query that i posted in your other thread.
Since the details in the other table TransactionDetail, you just need to INNER JOIN from the TransactionMaster to it and do the SUM(). I didn't verify the Dr - Cr or Cr - Dr logic. Please verify yourself.
SELECT t.*, v.FullName, o.Opening
FROM [TransactionMaster] t
INNER JOIN [VoucherType] v on t.VoucherTypeCode = v.VoucherTypeCode
OUTER APPLY
(
SELECT Opening = sum(case when m.[VoucherTypeCode] in (1, 3)
then - ISNULL(d.CrAmount, 0)
else + ISNULL(d.CrAmount, 0)
end)
FROM [TransactionMaster] m
INNER JOIN [TransactionDetail] d ON m.ID = d.TransactionCode
WHERE m.TransactionDate < t.TransactionDate
) o
WHERE t.TransactionDate BETWEEN '2018-03-23' AND '2018-03-24'
order by t.TransactionDate
EDIT:
You don't need to use FULL JOIN to identify IN and OUT. Just use CASE statement as below
SELECT inID = case when t.VoucherTypeCode in (1,3) then t.ID end,
inAmount = case when t.VoucherTypeCode in (1,3) then a.Amount end,
outID = case when t.VoucherTypeCode in (2,4) then t.ID end,
outAmount = case when t.VoucherTypeCode in (2,4) then a.Amount end,
t.PayeeName, t.TransactionDate, t.RefNo,
v.FullName, Opening = isnull(o.Opening, 0)
FROM [TransactionMaster] t
INNER JOIN [VoucherType] v on t.VoucherTypeCode = v.VoucherTypeCode
CROSS APPLY
(
SELECT Amount = sum(case when m.[VoucherTypeCode] in (1, 3)
then -CrAmount
else DrAmount
end)
FROM [TransactionMaster] m
INNER JOIN [TransactionDetail] d ON m.ID = d.TransactionCode
WHERE m.ID = t.ID
) a
OUTER APPLY
(
SELECT Opening = sum(case when m.[VoucherTypeCode] in (1, 3)
then -CrAmount
else DrAmount
end)
FROM [TransactionMaster] m
INNER JOIN [TransactionDetail] d ON m.ID = d.TransactionCode
WHERE m.TransactionDate < t.TransactionDate
) o
order by t.TransactionDate

Get the opening and closing balance

I have this table structure and query written with the help of some guy here and it works perfect. I want to get the opening and closing balance between the dates. I have commented the date on which I want to get the date and if I run that date check the expected output I want is shown below.
Here is the structure and sample data:
DROP TABLE [TransactionMaster];
DROP TABLE [VoucherType];
CREATE TABLE [VoucherType](
[VoucherTypeCode] [tinyint] NOT NULL PRIMARY KEY,
[FullName] [nvarchar](255) NOT NULL
);
INSERT INTO [VoucherType] VALUES (1, 'Cash Payment Voucher');
INSERT INTO [VoucherType] VALUES (2, 'Cash Receipt Voucher');
INSERT INTO [VoucherType] VALUES (3, 'Bank Payment Voucher');
INSERT INTO [VoucherType] VALUES (4, 'Bank Receipt Voucher');
CREATE TABLE [TransactionMaster](
[ID] [bigint] NOT NULL PRIMARY KEY,
[VoucherTypeCode] [tinyint] NOT NULL,
[PayeeName] [varchar](255) NOT NULL,
[TransactionDate] datetime,
[Amount] NUMERIC,
[RefNo] [nvarchar](50) NULL
CONSTRAINT [FK_tbl_TransactionMaster_tbl_VoucherType] FOREIGN KEY([VoucherTypeCode])
REFERENCES [VoucherType] ([VoucherTypeCode])
)
INSERT INTO [TransactionMaster] VALUES (1, 2, 'Asim', '2018-03-21', '2500', 'CRV-0001-LHR');
INSERT INTO [TransactionMaster] VALUES (2, 4, 'Ali', '2018-03-21', '1150', 'BRV-2421-KHI');
INSERT INTO [TransactionMaster] VALUES (3, 1, 'Erick', '2018-03-23', '1200', 'CPV-5435-ISL');
INSERT INTO [TransactionMaster] VALUES (4, 3, 'Asim', '2018-03-24', '1000', 'BPV-2345-CAN');
INSERT INTO [TransactionMaster] VALUES (5, 2, 'Mehboob', '2018-03-25', '2400', 'CRV-2976-PSH');
INSERT INTO [TransactionMaster] VALUES (6, 1, 'Erick', '2018-03-25', '2900', 'CPV-2323-KOH');
INSERT INTO [TransactionMaster] VALUES (7, 1, 'Feroze', '2018-03-21', '3100', 'CRV-0531-SRG');
INSERT INTO [TransactionMaster] VALUES (8, 3, 'Ali', '2018-03-21', '500', 'BRV-2001-RWP');
Here is the query
with data1 as (
select a.id inid,a.VoucherTypeCode,PayeeName,a.Amount InAmount,TransactionDate,RefNo,FullName from TransactionMaster a inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
where a.VoucherTypeCode in (1,3)
),
data2 as (
select a.id outid,a.VoucherTypeCode,PayeeName,a.Amount OutAmount,TransactionDate,RefNo,FullName from TransactionMaster a inner join [VoucherType] b on a.VoucherTypeCode = b.VoucherTypeCode
where a.VoucherTypeCode in (2,4)
)
select *,COALESCE(a.TransactionDate,b.TransactionDate) as FullDate from data1 a full join data2 b on inid = outid and a.TransactionDate = b.TransactionDate
--WHERE COALESCE(a.TransactionDate,b.TransactionDate) BETWEEN '2018-03-23 00:00:00.000' AND '2018-03-24 00:00:00.000'
order by FullDate
The output right now is like this::
inid VoucherTypeCode PayeeName InAmount TransactionDate RefNo FullName outid VoucherTypeCode PayeeName OutAmount TransactionDate RefNo FullName FullDate
-------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------
7 1 Feroze 3100 2018-03-21 00:00:00.000 CRV-0531-SRG Cash Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-21 00:00:00.000
8 3 Ali 500 2018-03-21 00:00:00.000 BRV-2001-RWP Bank Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-21 00:00:00.000
NULL NULL NULL NULL NULL NULL NULL 2 4 Ali 1150 2018-03-21 00:00:00.000 BRV-2421-KHI Bank Receipt Voucher 2018-03-21 00:00:00.000
NULL NULL NULL NULL NULL NULL NULL 1 2 Asim 2500 2018-03-21 00:00:00.000 CRV-0001-LHR Cash Receipt Voucher 2018-03-21 00:00:00.000
3 1 Erick 1200 2018-03-23 00:00:00.000 CPV-5435-ISL Cash Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-23 00:00:00.000
4 3 Asim 1000 2018-03-24 00:00:00.000 BPV-2345-CAN Bank Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-24 00:00:00.000
6 1 Erick 2900 2018-03-25 00:00:00.000 CPV-2323-KOH Cash Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-25 00:00:00.000
NULL NULL NULL NULL NULL NULL NULL 5 2 Mehboob 2400 2018-03-25 00:00:00.000 CRV-2976-PSH Cash Receipt Voucher 2018-03-25 00:00:00.000
The expected output is this:
inid VoucherTypeCode PayeeName InAmount TransactionDate RefNo FullName outid VoucherTypeCode PayeeName OutAmount TransactionDate RefNo FullName FullDate Opening
-------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- --------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------- ----------------------- -------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------
3 1 Erick 1200 2018-03-23 00:00:00.000 CPV-5435-ISL Cash Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-23 00:00:00.000 -50
4 3 Asim 1000 2018-03-24 00:00:00.000 BPV-2345-CAN Bank Payment Voucher NULL NULL NULL NULL NULL NULL NULL 2018-03-24 00:00:00.000 1150
The formula is that (Opening+InAmount) - Out Amount will be the Closing Balance and Opening will be previous rows Closing Balance.
So for first record opening will be 0 and closing will be 3100 and for second opening = 3100 and closing 3600 and so on.
use OUTER APPLY to calculate the Amount before the date.
use conditional SUM() to calculate the amount
select *
from [TransactionMaster] m
inner join [VoucherType] t on m.VoucherTypeCode = t.VoucherTypeCode
outer apply
(
select Opening = sum(case when [VoucherTypeCode] in (1, 3)
then Amount
else -Amount
end)
from [TransactionMaster] x
where x.TransactionDate < m.TransactionDate
) o
where m.TransactionDate between '2018-03-23' and '2018-03-24'
order by ID
Explanation on the CASE WHEN statement
the amount is treated as IN or OUT depending on the VoucherTypeCode.
For code 1 and 3 it is IN / positive and others is OUT / negative
What the case statement does is to convert the amount to positive or negative value depending on the VoucherTypeCode
SELECT VoucherTypeCode, Amount
case when [VoucherTypeCode] in (1, 3)
then +Amount
else -Amount
end
FROM ...
SO basically you will get
1 2 2500 -2500
2 4 1150 -1150
3 1 1200 1200
so when you SUM() it up, it will be -2500 - 1150 + 1200 + . .

Breaking data into multiple columns

I am working on a query where I require data to be divided in multiple columns based on the type of the value in it. I have a Voucher Type table where I am defining types now I want payment and receipt to be divided in two columns.
Here is the structure of the tables and sample data:
DROP TABLE [TransactionMaster];
DROP TABLE [VoucherType];
CREATE TABLE [VoucherType](
[VoucherTypeCode] [tinyint] NOT NULL PRIMARY KEY,
[FullName] [nvarchar](255) NOT NULL
);
INSERT INTO [VoucherType] VALUES (1, 'Cash Payment Voucher');
INSERT INTO [VoucherType] VALUES (2, 'Cash Receipt Voucher');
INSERT INTO [VoucherType] VALUES (3, 'Bank Payment Voucher');
INSERT INTO [VoucherType] VALUES (4, 'Bank Receipt Voucher');
CREATE TABLE [TransactionMaster](
[ID] [bigint] NOT NULL PRIMARY KEY,
[VoucherTypeCode] [tinyint] NOT NULL,
[PayeeName] [varchar](255) NOT NULL,
[RefNo] [nvarchar](50) NULL
CONSTRAINT [FK_tbl_TransactionMaster_tbl_VoucherType] FOREIGN KEY([VoucherTypeCode])
REFERENCES [VoucherType] ([VoucherTypeCode])
)
INSERT INTO [TransactionMaster] VALUES (1, 2, 'Asim', 'CRV-0001-LHR');
INSERT INTO [TransactionMaster] VALUES (2, 4, 'Ali', 'BRV-2421-KHI');
INSERT INTO [TransactionMaster] VALUES (3, 1, 'Erick', 'CPV-5435-ISL');
INSERT INTO [TransactionMaster] VALUES (4, 3, 'Asim', 'BPV-2345-CAN');
INSERT INTO [TransactionMaster] VALUES (5, 2, 'Mehboob', 'CRV-2976-PSH');
INSERT INTO [TransactionMaster] VALUES (6, 1, 'Erick', 'CPV-2323-KOH');
This is the query.
SELECT [Master].[RefNo], [Type].[FullName] [V.Type], [Master].[PayeeName]
FROM [TransactionMaster] [Master], [VoucherType] [Type]
WHERE [Type].[VoucherTypeCode] = [Master].[VoucherTypeCode]
Inward Outward
RefNo V.Type PayeeName RefNo V.Type PayeeName
CPV-5435-ISL Cash Payment Voucher Erick CRV-0001-LHR Cash Receipt Voucher Asim
BPV-2345-CAN Bank Payment Voucher Asim BRV-2421-KHI Bank Receipt Voucher Ali
CPV-2323-KOH Cash Payment Voucher Erick CRV-2976-PSH Cash Receipt Voucher Mehboob
So basically if the VoucherCode is 1 or 3 it'll be in Inward part columns and if the VoucherCode is 2 or 4 then it'll be in outward part columns.
So I require total six columns instead of three in one row. Hope this can be done. Outward and Inward is just to clear out columns part they are not required to be shown or something.
Check out this:
select tb1.Refno, tb1.[FullName] as VType, tb1.PayeeName, tb2.Refno, tb2.[FullName] as VType, tb2.PayeeName from(
(select ROW_NUMBER()over (order by id) as rowid, TransactionMaster.RefNo, TransactionMaster.PayeeName, [VoucherType].FullName
from TransactionMaster
inner join [VoucherType] on TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
where TransactionMaster.[VoucherTypeCode] in (1,3))tb1
full outer join
(select ROW_NUMBER()over (order by id) as rowid, TransactionMaster.RefNo, TransactionMaster.PayeeName, [VoucherType].FullName
from TransactionMaster
inner join [VoucherType] on TransactionMaster.VoucherTypeCode = [VoucherType].VoucherTypeCode
where TransactionMaster.[VoucherTypeCode] in (2,4)
) tb2 on tb1.rowid = tb2.rowid)

how to filter multiple rows in a sql table based on two columns

ID |Number|Qty|OrderNumber|Date
456-98A|746-96|0.1|00 |2015-01-01
456-98A|746-96|0.1|00 |2015-01-01
456-98A|746-96|0.1|00 |2015-01-01
456-98A|746-96|0.1|00 |2015-01-01
456-98A|321-96|0.3|05 |2015-01-01
456-98A|321-96|0.3|05 |2015-01-01
the above table in sql gives me multiple rows of the same ID.How do i filter this data so that if the Number and orderNumber is the same it must give me only one row for that ID instead of multiple values.for eg the expected outcome would be
ID |Number|Qty|OrderNumber|Date
456-98A|746-96|0.1|00 |2015-01-01
456-98A|321-96|0.3|05 |2015-01-01
You can group by column you need or all or distinct.
select ID, Number, Qty, OrderNumber, Date from YourTable
group by ID, Number, Qty, OrderNumber, Date
You can use ROW_NUMBER() with PARTITION BY like this
SQL Fiddle
Query
SELECT ID, Number,Qty,OrderNumber,Date
FROM
(
SELECT ID, Number,Qty,OrderNumber,Date,ROW_NUMBER()OVER(PARTITION BY Number, orderNumber ORDER BY ID ) as rn
FROM yourTable
)yourTable
WHERE rn = 1
Sample Data
CREATE TABLE yourTable
([ID] varchar(7), [Number] varchar(6), [Qty] int, [OrderNumber] int, [Date] datetime);
INSERT INTO yourTable
([ID], [Number], [Qty], [OrderNumber], [Date])
VALUES
('456-98A', '746-96', 0.1, 00, '2015-01-01 00:00:00'),
('456-98A', '746-96', 0.1, 00, '2015-01-01 00:00:00'),
('456-98A', '746-96', 0.1, 00, '2015-01-01 00:00:00'),
('456-98A', '746-96', 0.1, 00, '2015-01-01 00:00:00'),
('456-98A', '321-96', 0.3, 05, '2015-01-01 00:00:00'),
('456-98A', '321-96', 0.3, 05, '2015-01-01 00:00:00');
Output
ID Number Qty OrderNumber Date
456-98A 321-96 0 5 2015-01-01 00:00:00.000
456-98A 746-96 0 0 2015-01-01 00:00:00.000
If you can use a temporary table, you can do :
CREATE TABLE #tempo
([rowNum] identity, [ID] varchar(7), [Number] varchar(6), [Qty] int, [OrderNumber] int, [Date] datetime);
INSERT INTO #tempo ([ID], [Number], [Qty], [OrderNumber], [Date])
SELECT [ID], [Number], [Qty], [OrderNumber], [Date] FROM yourtable
And to get the right rows:
SELECT t1.[ID], t1.[Number], t1.[Qty], t1.[OrderNumber], t1.[Date]
FROM #tempo AS t1
WHERE NOT EXISTS (SELECT 1
FROM #tempo AS t2
WHERE t2.ID = t1.ID
AND t2.Number = t2.Number
-- **and other columns if needed**
AND t2.RowNum > t1.RowNum)

Resources