Get child accounts - sql-server

I have this table structure and some sample data as well. The logic here is that against any COATitle I enter child records that are the expenditures against that specific head account. In my sample data as Medical have multiple child records and same as Incentive.
My problem is that when I select specific head account like if I select Medical it should show its child records in this case they should not include records with MasterID 2 as they are of Incentive
CREATE TABLE TransactionMaster
(
ID Int,
TransactionCode VARCHAR(25),
PRIMARY KEY (ID)
)
INSERT INTO TransactionMaster VALUES (1, 'TRA-001');
INSERT INTO TransactionMaster VALUES (2, 'TRA-002');
INSERT INTO TransactionMaster VALUES (3, 'TRA-003');
CREATE TABLE TransactionDetail
(
ID Int,
MasterID Int,
COATitle VARCHAR(25),
CrAmount NUMERIC(18,2),
DrAmount NUMERIC(18,2),
PRIMARY KEY (ID),
FOREIGN KEY (MasterID) REFERENCES TransactionMaster(ID)
)
INSERT INTO TransactionDetail VALUES (1, 1, 'Medical', '2500', NULL)
INSERT INTO TransactionDetail VALUES (2, 1, 'Travelling', NULL, '2500')
INSERT INTO TransactionDetail VALUES (3, 1, 'Medicine', NULL, '2500')
INSERT INTO TransactionDetail VALUES (4, 1, 'Doc Fee', NULL, '2500')
INSERT INTO TransactionDetail VALUES (5, 2, 'Incentive', '3000', NULL)
INSERT INTO TransactionDetail VALUES (6, 2, 'Extra', NULL, '2500')
INSERT INTO TransactionDetail VALUES (7, 2, 'Bonus', NULL, '500')
INSERT INTO TransactionDetail VALUES (8, 3, 'Medical', NULL, '3000')
INSERT INTO TransactionDetail VALUES (9, 3, 'Tests', '2500', NULL)
INSERT INTO TransactionDetail VALUES (10, 3, 'Juice', '500', NULL)
Query Sample:
SELECT [Voucher].[TransactionCode], [Detail].[COATitle], [Detail].[CrAmount], [Detail].[DrAmount]
FROM [TransactionMaster] [Voucher], [TransactionDetail] [Detail]
WHERE [Voucher].[ID] = [Detail].[MasterID] AND COATitle NOT IN ('Medical')
OutPut:
TransactionCode COATitle CrAmount DrAmount
------------------------- ------------------------- --------------------------------------- ---------------------------------------
TRA-001 Travelling NULL 2500.00
TRA-001 Medicine NULL 2500.00
TRA-001 Doc Fee NULL 2500.00
TRA-002 Incentive 3000.00 NULL
TRA-002 Extra NULL 2500.00
TRA-002 Bonus NULL 500.00
TRA-003 Tests 2500.00 NULL
TRA-003 Juice 500.00 NULL
The desired output shouldn't include rows with TransactionCode with 'TRA-002'.

Try the following query
SELECT
m.TransactionCode,
d.COATitle,
d.CrAmount,
d.DrAmount
FROM TransactionDetail d
JOIN TransactionMaster m ON d.MasterID=m.ID
WHERE d.MasterID IN(
SELECT MasterID
FROM TransactionDetail
WHERE COATitle='Medical'
)
AND d.COATitle<>'Medical'

Related

UPDATE using Rank(), Row_Number excluding duplicate values

I've a dataset similar to the one below.
I need to update the base lookup table based on the values provided in the updated_CustomerId column. The base tables is the same as the dataset but it does not have updated_CustomerId column.
The challenge here that the base table has a unique constraint based on combination of three columns below:
Current_CustomerID
Order_ID
OrderCategory
DESIRED OUTPUT:
After the update either one of Old_customerIds (17360410 - Pk 8, 21044488 - Pk = 9) can be reassigned to the Update_CustomerID
PrimaryKey 2 will not updated as that would lead to Unique constraint violation, but it will then be deleted along with one of the PrimaryKeys from the above either 8 or 9, depending on which one was updated (re-assigned to the new id)
After everything is updated on the base table I then delete from the base table all records where Current_CustomerID was not re-assigned to the updated_CustomerId (if different)
IF OBJECT_ID('tempdb..#DataSet') IS NOT NULL
DROP TABLE #DataSet
IF OBJECT_ID('tempdb..#BaseTable') IS NOT NULL
DROP TABLE #BaseTable
CREATE TABLE #DataSet
(
PrimaryKey INT NOT NULL CONSTRAINT [PK_dataset_ID] PRIMARY KEY,
Current_CustomerID INT NOT NULL,
Order_ID INT NOT NULL,
OrderCategory VARCHAR(50) NOT NULL,
Updated_CustomerId INT NOT NULL
)
INSERT INTO #DataSet (PrimaryKey, Current_CustomerID, Order_ID, OrderCategory, updated_CustomerId)
VALUES
(1, 17395001, 4451784, 'Kitchen', 25693110),
(2, 25693110, 4451784, 'Kitchen', 25693110),
(3, 25693110, 2083059, 'Kitchen', 25693110),
(4, 25693110, 2163679, 'Kitchen', 25693110),
(5, 25693110, 2171466, 'Kitchen', 25693110),
(6, 25693110, 2163679, 'Bathroom', 25693110),
(7, 25693110, 2171466, 'Bathroom', 25693110),
(8, 17360410, 3377931, 'Furniture', 16303984),
(9, 21044488, 3377931, 'Furniture', 16303984),
(10, 1534323, 2641714, 'Furniture', 16303984),
(11, 16303984, 2641726, 'Furniture', 16303984),
(12, 16303984, 2641793, 'Furniture', 16303984),
(13, 16303984, 2641816, 'Furniture', 16303984),
(14, 16303345, 2641816, 'Garden', 16301239),
(15, 12345678, 1239065, 'Medicine', 1075432)
CREATE TABLE #BaseTable
(
PrimaryKey INT NOT NULL CONSTRAINT [PK_baseTable_ID] PRIMARY KEY,
CustomerID INT NOT NULL,
Order_ID INT NOT NULL,
OrderCategory VARCHAR(50) NOT NULL,
)
CREATE UNIQUE NONCLUSTERED INDEX [IDX_LookUp] ON #BaseTable
(
CustomerID ASC,
Order_ID ASC,
OrderCategory ASC
) ON [PRIMARY]
INSERT INTO #BaseTable (PrimaryKey, CustomerID, Order_ID, OrderCategory)
VALUES
(1, 17395001, 4451784, 'Kitchen'),
(2, 25693110, 4451784, 'Kitchen'),
(3, 25693110, 2083059, 'Kitchen'),
(4, 25693110, 2163679, 'Kitchen'),
(5, 25693110, 2171466, 'Kitchen'),
(6, 25693110, 2163679, 'Bathroom'),
(7, 25693110, 2171466, 'Bathroom'),
(8, 17360410, 3377931, 'Furniture'),
(9, 21044488, 3377931, 'Furniture'),
(10, 1534323, 2641714, 'Furniture'),
(11, 16303984, 2641726, 'Furniture'),
(12, 16303984, 2641793, 'Furniture'),
(13, 16303984, 2641816, 'Furniture'),
(14, 16303345, 2641816, 'Garden'),
(15, 12345678, 1239065, 'Medicine')
-- select * from #BaseTable
-- select * from #DataSet
; with CTE AS (
select a.*
,rank() over (partition by a.updated_CustomerId, a.Order_ID, a.OrderCategory
order by a.Current_CustomerID) as flag
from #DataSet a
)
with CTE AS (
select a.*
,rank() over (partition by a.updated_CustomerId, a.Order_ID, a.OrderCategory order by a.Current_CustomerID) as flag
from #DataSet a
)
update b
set CustomerID = a.Updated_CustomerId
from #BaseTable b
inner join CTE a on b.PrimaryKey = a.PrimaryKey
where flag <> 2
Msg 2601, Level 14, State 1, Line 82
Cannot insert duplicate key row in object 'dbo.#BaseTable' with unique index 'IDX_LookUp'. The duplicate key value is (25693110, 4451784, Kitchen).
The statement has been terminated.
I think you just want to get a row_number for the #DataTable, and then delete where there are more than one based on the unique key:
//...
DELETE bt
FROM #BaseTable bt
INNER JOIN (
SELECT a.PrimaryKey,
a.Updated_CustomerId,
a.Order_ID,
a.OrderCategory,
row = ROW_NUMBER() OVER (PARTITION BY a.Updated_CustomerId, a.Order_ID, a.OrderCategory ORDER BY a.Current_CustomerID)
FROM #BaseTable b
INNER JOIN #DataSet a
ON b.PrimaryKey = a.PrimaryKey
) x
ON bt.PrimaryKey = x.PrimaryKey
AND x.row > 1

Filter Table Before Applying Right Join ON 3RD TABLE

Using MSSQL: Just for clarification
Customer Table
CustomerNumber Name
===================
1 David
2 Thomas
3 Mangold
4 Issac
------------------------------------------------------------
CustomerAddress Table
CustomerNumber State EffectiveDate
==================================
1 AL 01/01/2017
1 VA 06/01/2017
1 GA 02/01/2018
1 FL 10/01/2018
2 TX 01/01/2017
3 MA
4 IL 04/01/2015
SalesOrder Table
CUSTOMER ORDERNo OrderDate
========================
1 1000 03/01/2017
2 1001 10/10/2017
1 1002 11/01/2017
3 1003 12/01/2017
4 1004 01/01/2018
1 1005 02/01/2018
1 1006 01/01/2019
I need to fetch all the orders with the customer detail and the customer address on the order date.
SELECT T1.ORDERNo, T1.ORDERDATE, T1.CUSTOMER, T2.NAME, T3.STATE
FROM SALESORDER T1, CUSTOMER T2, CUSTOMERADDRESS T3
RIGHT JOIN(
SELECT CUSTOMER, MAX(EFFECTIVEDATE) FROM CUSTOMERADDRESS
--WHERE EFFECTIVEDATE <= T1.ORDERDATE
GROUP BY CUSTOMER)T4
ON T3.CUSTOMER = T4.CUSTOMER AND T3.EFFECTIVEDATE=T4.EFFECTIVEDATE
WHERE T1.CUSTOMER = T2.CUSTOMERNUMBER
AND T1.CUSTOMER = T3.CUSTOMERNUMBER
Want to see how to do compare in the join where i compare first table to the 3rd table in the join. see the commented code --WHERE EFFECTIVEDATE <= T1.ORDERDATE
If I remove the commented code, the table in the join cannot reference a table outside.
The expected output is:
CUSTOMER ORDERNo OrderDate CustomerName State
=============================================
1 1000 03/01/2017 David AL
2 1001 10/10/2017 Thomas TX
1 1002 11/01/2017 David VA
3 1003 12/01/2017 Mangold MA
4 1004 01/01/2018 Issac IL
1 1005 02/01/2018 David GA
1 1006 01/01/2019 David FL
The tables in sql fiddle http://sqlfiddle.com/#!18/9eecb:
CREATE TABLE Customer
('CustomerNumber' int, 'CustomerName' varchar(30))
;
INSERT INTO Customer
('CustomerNumber', 'CustomerName')
VALUES
(1, 'David'),
(2, 'Thomas'),
(3, 'Mangold'),
(4, 'Issac')
;
CREATE TABLE CustomerAddress
('CustomerNumber' int, 'State' varchar(2), 'EffectiveDate' date)
;
INSERT INTO CustomerAddress
('CustomerNumber', 'State', 'EffectiveDate')
VALUES
(1, 'AL', 01/01/2017),
(1, 'VA', 06/01/2017),
(1, 'GA', 02/01/2018),
(1, 'FL', 10/01/2018),
(2, 'TX', 01/01/2017),
(3, 'MA',),
(4, 'IL', 04/01/2015)
;
CREATE TABLE SalesOrder
('CUSTOMER' int, 'ORDERNO' int, 'OrderDate' Date)
;
INSERT INTO SalesOrder
('CUSTOMER', 'ORDERNO', 'OrderDate')
VALUES
(1, 1000, 03/01/2017),
(2, 1001, 10/10/2017),
(1, 1002, 11/01/2017),
(3, 1003, 12/01/2017),
(4, 1004, 01/01/2018),
(1, 1005, 02/01/2018),
(1, 1006, 01/01/2019)
;
CREATE TABLE CustomerAddress
(`CustomerNumber` int, 'State' varchar(2), `EffectiveDate` date)
;
INSERT INTO CustomerAddress
(`CustomerNumber`, `State`, 'EffectiveDate')
VALUES
(1, 'AL', 01/01/2017),
(1, 'VA', 06/01/2017),
(1, 'GA', 02/01/2018),
(1, 'FL', 10/01/2018),
(2, 'TX', 01/01/2017),
(3, 'MA',),
(4, 'IL', 04/01/2015)
;
CREATE TABLE SalesOrder
(`CUSTOMER` int, 'ORDERNO' int, `OrderDate` Date)
;
INSERT INTO SalesOrder
(`CUSTOMER `, `ORDERNO`, 'OrderDate')
VALUES
(1, 1000, 03/01/2017),
(2, 1001, 10/10/2017),
(1, 1002, 11/01/2017),
(3, 1003, 12/01/2017),
(4, 1004, 01/01/2018),
(1, 1005, 02/01/2018),
(1, 1006, 01/01/2019)
;
'sql server version'
CREATE TABLE Customer
(CustomerNumber int, CustomerName varchar(30))
;
INSERT INTO Customer
(CustomerNumber, CustomerName)
VALUES
(1, 'David'),
(2, 'Thomas'),
(3, 'Mangold'),
(4, 'Issac');
;
CREATE TABLE CustomerAddress
(CustomerNumber int, State varchar(2), EffectiveDate date)
;
INSERT INTO CustomerAddress
(CustomerNumber, State, EffectiveDate)
VALUES
(1, 'AL', '01/01/2017'),
(1, 'VA', '06/01/2017'),
(1, 'GA', '02/01/2018'),
(1, 'FL', '10/01/2018'),
(2, 'TX', '01/01/2017'),
(4, 'IL', '04/01/2015')
;
INSERT INTO CustomerAddress
(CustomerNumber, State)
VALUES
(3, 'MA' )
;
CREATE TABLE SalesOrder
(CUSTOMER int, ORDERNO int, OrderDate Date)
;
INSERT INTO SalesOrder
(CUSTOMER, ORDERNO, OrderDate)
VALUES
(1, 1000, '03/01/2017'),
(2, 1001, '10/10/2017'),
(1, 1002, '11/01/2017'),
(3, 1003, '12/01/2017'),
(4, 1004, '01/01/2018'),
(1, 1005, '02/01/2018'),
(1, 1006, '01/01/2019')
;
The problem: Need to Pick all the Sales Orders and their customer Name, and the Customer Address. The important and tricky part is the customer address changes based on the date of the sales order.
--MODIFIED VERSION OF THE INCOMPLETE QUERY
SELECT T1.ORDERNo, T1.ORDERDATE, T1.CUSTOMER, T2.CustomerName, T3.STATE
FROM CUSTOMER T2, SALESORDER T1 INNER JOIN CUSTOMERADDRESS T3 ON T1.CUSTOMER = T3.CUSTOMERNUMBER
RIGHT JOIN(
SELECT CustomerNumber, MAX(EFFECTIVEDATE) as EffectiveDate4 FROM CUSTOMERADDRESS
--WHERE EFFECTIVEDATE < T1.ORDERDATE
GROUP BY CustomerNumber
--HAVING EFFECTIVEDATE < T1.ORDERDATE
) T4
ON T3.CustomerNumber = T4.CustomerNumber AND T3.EFFECTIVEDATE=T4.EffectiveDate4
WHERE T1.CUSTOMER = T2.CUSTOMERNUMBER
OUTER APPLY should solve your problem. based on your needs you can change your query.
SELECT T1.ORDERNo, T1.ORDERDATE, T1.CUSTOMER, T2.NAME, T3.STATE
FROM SALESORDER T1, CUSTOMER T2, CUSTOMERADDRESS T3
OUTER APPLY(
SELECT CUSTOMER, MAX(EFFECTIVEDATE) FROM CUSTOMERADDRESS
WHERE EFFECTIVEDATE <= T1.ORDERDATE
AND T3.CUSTOMER = CUSTOMER )T4
WHERE T1.CUSTOMER = T2.CUSTOMERNUMBER
AND T1.CUSTOMER = T3.CUSTOMERNUMBER
AND T3.EFFECTIVEDATE = T4.EFFECTIVEDATE

Get not selected word in column

I have this table structure and data and query that is giving me the child records. This is giving me required data as I wanted now there is another requirements that popped up with time that I want to show the name of the COA which is not selected here i.e Medical
CREATE TABLE TransactionMaster
(
ID Int,
TransactionCode VARCHAR(25),
PRIMARY KEY (ID)
)
INSERT INTO TransactionMaster VALUES (1, 'TRA-001');
INSERT INTO TransactionMaster VALUES (2, 'TRA-002');
INSERT INTO TransactionMaster VALUES (3, 'TRA-003');
CREATE TABLE TransactionDetail
(
ID Int,
MasterID Int,
COATitle VARCHAR(25),
CrAmount NUMERIC(18,2),
DrAmount NUMERIC(18,2),
PRIMARY KEY (ID),
FOREIGN KEY (MasterID) REFERENCES TransactionMaster(ID)
)
INSERT INTO TransactionDetail VALUES (1, 1, 'Medical', '2500', NULL)
INSERT INTO TransactionDetail VALUES (2, 1, 'Travelling', NULL, '2500')
INSERT INTO TransactionDetail VALUES (3, 1, 'Medicine', NULL, '2500')
INSERT INTO TransactionDetail VALUES (4, 1, 'Doc Fee', NULL, '2500')
INSERT INTO TransactionDetail VALUES (5, 2, 'Incentive', '3000', NULL)
INSERT INTO TransactionDetail VALUES (6, 2, 'Extra', NULL, '2500')
INSERT INTO TransactionDetail VALUES (7, 2, 'Bonus', NULL, '500')
INSERT INTO TransactionDetail VALUES (8, 3, 'Medical', NULL, '3000')
INSERT INTO TransactionDetail VALUES (9, 3, 'Tests', '2500', NULL)
INSERT INTO TransactionDetail VALUES (10, 3, 'Juice', '500', NULL)
Sample Query:
SELECT
m.TransactionCode,
d.COATitle,
d.CrAmount,
d.DrAmount
FROM TransactionDetail d
JOIN TransactionMaster m ON d.MasterID=m.ID
WHERE d.MasterID IN(
SELECT MasterID
FROM TransactionDetail
WHERE COATitle='Medical'
)
AND d.COATitle<>'Medical'
Output giving:
TransactionCode COATitle CrAmount DrAmount
------------------------- ------------------------- --------------------------------------- ---------------------------------------
TRA-001 Travelling NULL 2500.00
TRA-001 Medicine NULL 2500.00
TRA-001 Doc Fee NULL 2500.00
TRA-003 Tests 2500.00 NULL
TRA-003 Juice 500.00 NULL
I want to include another column that'll show Medicalin it.
Expected Output:
TransactionCode COATitle CrAmount DrAmount COA
------------------------- ------------------------- --------------------------------------- ----------------------------- ------------------------
TRA-001 Travelling NULL 2500.00 Medical
TRA-001 Medicine NULL 2500.00 Medical
TRA-001 Doc Fee NULL 2500.00 Medical
TRA-003 Tests 2500.00 NULL Medical
TRA-003 Juice 500.00 NULL Medical
DECLARE #prm nvarchar(100)
SET #prm = 'Medical'
SELECT
m.TransactionCode,
d.COATitle,
d.CrAmount,
d.DrAmount,
#prm as COA
FROM TransactionDetail d
JOIN TransactionMaster m ON d.MasterID=m.ID
WHERE d.MasterID IN(
SELECT MasterID
FROM TransactionDetail
WHERE COATitle=#prm
)
AND d.COATitle<>#prm

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

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)

Resources