SQL - More efficient way instead of using a cursor - sql

-- Declare the table we are interested in reverting.
DECLARE #table_name VARCHAR(1000)
SET #table_name = 'tblCustomers' -- change this
-- Declare cursor and use the select statement (the one we want to loop through).
DECLARE customer_cursor CURSOR FOR
SELECT C.CustomerId
FROM tblCustomers C
WHERE ModifiedBy like '%crm%'
ORDER BY C.CustomerId DESC
-- Open the cursor and copy the columns into the original_consumer variable.
DECLARE #customer_id INT
OPEN customer_cursor
FETCH NEXT FROM customer_cursor
INTO #customer_id
-- Now loop through the old consumer id's and update their corresponding purchase and refunds records.
WHILE ##FETCH_STATUS = 0
BEGIN
IF EXISTS ( SELECT TOP 1 UserName
FROM tblAudit
WHERE TableName = #table_name
AND TableId IN (
SELECT CONVERT(VARCHAR, CustomerId)
FROM tblCustomers -- change this
WHERE CustomerId = #customer_id
)
AND UserName != 'crmuser'
ORDER BY TransactionDate DESC)
BEGIN
UPDATE tblCustomers
SET ModifiedBy = (SELECT TOP 1 UserName
FROM tblAudit
WHERE TableName = #table_name
AND TableId IN (
SELECT CONVERT(VARCHAR, CustomerId)
FROM tblCustomers -- change this
WHERE CustomerId = #customer_id
)
AND UserName != 'crmuser'
ORDER BY TransactionDate DESC),
ModifiedDate = (SELECT TOP 1 TransactionDate
FROM tblAudit
WHERE TableName = #table_name
AND TableId IN (
SELECT CONVERT(VARCHAR, CustomerId)
FROM tblCustomers -- change this
WHERE CustomerId = #customer_id
)
AND UserName != 'crmuser'
ORDER BY TransactionDate DESC)
WHERE CustomerId = #customer_id
END
FETCH NEXT FROM customer_cursor INTO #customer_id
END
-- Finally close and deallocate the cursor to stop memory leakage.
CLOSE customer_cursor
DEALLOCATE customer_cursor

This looks like it might work:
UPDATE tblCustomers
SET ModifiedBy = a.UserName,
ModofiedDate = amax.LatestChangeDate
from tblCustomers t
inner join -- get the latest transaction_date for each customer
(
select customerId, max(transaction_date) LatestChangeDate
from tblAudit
where TableName = #table_name
) amax on amax.customerId = t.customer_id
inner join -- get the details of changes for customer and latest date
(
select CustomerId, UserName, transaction_date
from tblAudit
where table_name = #table_name
) a on a.customerId = t.customerId and a.transaction_date = amax.LatestChangeDate
WHERE t.CustomerId = #customer_id
);
(I might have some of the column names wrong.)

BEGIN TRAN
SELECT COUNT(*)
FROM tblInvoices
WHERE ModifiedBy = 'DataImporterUser'
;WITH cte AS
(
SELECT TableId,
TransactionDate,
UserName,
TransactionDetail,
ROW_NUMBER() OVER (PARTITION BY TableId ORDER BY TransactionDate DESC) AS rn
FROM tblAudit
WHERE TableName = 'tblInvoices'
AND UserName <> 'DataImporterUser'
)
UPDATE C
SET C.ModifiedBy = cte.UserName,
C.ModifiedDate = cte.TransactionDate
FROM tblInvoices AS C
INNER JOIN cte
ON cte.TableId = C.InvoiceId
WHERE rn = 1
SELECT COUNT(*)
FROM tblEvents
WHERE ModifiedBy = 'DataImporterUser'
ROLLBACK

Related

Exclude specific rows from table in Stored Procedure

I have a table named Blacklist and table named Order.
Both have CustomerId column.
Stored Procedure ExecOrder manipulates Order table.
My goal is to exclude Orders that have Blacklisted CustomerId (meaning : Order's CustomerId is in Blacklist table).
I edited ExecOrder SP like this:
DECLARE #Temp TABLE
(
CustomerId UNIQUEIDENTIFIER
);
INSERT INTO #Temp
SELECT RightSide
FROM Blacklist
WHERE LeftSide = #CustomerId;
BEGIN
DECLARE db_cursor CURSOR
FOR SELECT OrderId
FROM dbo.[Order] ord
LEFT OUTER JOIN #Temp t ON t.CustomerId <> ord.CustomerId AND ord.CustomerId <> #CustomerId
WHERE AssetId = #BaseAsset
AND CurrencyId = #QuoteAsset
AND OrderTypeId <> #OrderType
AND [QuotePrice] <= #QuotePrice
AND OrderStatusId = 10
AND Amount > ISNULL(AmountFilled, 0)
AND OrderId < #OrderId
AND OrderBookId = #OrderBookId
AND DeliveryStart = #DeliveryPeriodStart
AND DeliveryEnd = #DeliveryPeriodEnd
AND #MinAmount <= Amount - ISNULL(AmountFilled, 0)
ORDER BY OrderDate;
END;
#Temp table returns correct list of CustomerIds.
Problem is that blacklisted orders are not excluded.
Your #Temp table is holding blacklisted customers.
-- contains blacklisted customer
INSERT INTO #Temp
SELECT RightSide
FROM Blacklist
WHERE LeftSide = #CustomerId;
Now, you need to select orders of customers not existing in #Temp table.
-- You need to select orders, where customerId not exists in #Temp table
SELECT OrderId
FROM dbo.[Order] ord
WHERE NOT EXISTS(SELECT 1 from #Temp WHERE customerId = ord.CustomerId) ...
You should connect with blacklist and take only where connected blacklist not existst:
LEFT OUTER JOIN #Temp t ON t.CustomerId <> ord.CustomerId AND ord.CustomerId <> #CustomerId
Change to:
LEFT OUTER JOIN #Temp t ON t.CustomerId = ord.CustomerId OR ord.CustomerId = #CustomerId
Next you should check if it is empty:
WHERE ... AND t.CustomerId IS NULL

Display Customer and all of their order dates on single row

I have a customers table and an orders table. I want to display the customer and all of his/her order dates on one row, rather than multiple rows. Here is what I have and what I'm looking for:
Basic code to get results:
select customerid, name, orderdate
from customer_table c inner join
order_table o
on c.customerid = o.customerid
this will work at the most you cant show it on different columns having nulls:
select customer_id,name,LISTAGG(orderdate, ', ') WITHIN GROUP (ORDER BY orderdate)
from(select customerid, name, orderdate
from customer_table c inner join
order_table o
on c.customerid = o.customerid );
You can use the following because you're bound by the 12 order limit. If you expand to an unknown number of orders with no upper limit, then you would need to use dynamic SQL and even then it would be tricky, because you would also need to dynamically create unique column names.
This query batches by customer and sets the order values. They will be in dated order and set as NULL if there's no more orders. It kinda assumes that at least one customer has 12 orders. You'll get a column of all NULLS if that's not the case
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
IF OBJECT_ID('tempdb..#sortedRows') IS NOT NULL DROP TABLE #SortedRows
DECLARE #CustomerList TABLE(CustomerID INT, RowNo INT);
INSERT INTO #CustomerList SELECT DISTINCT CustomerID, ROW_NUMBER() OVER(ORDER BY CustomerID) RowNo FROM Customer_Table (NOLOCK)
DECLARE #Count INT = (SELECT COUNT(DISTINCT CustomerID) RowNumber FROM #CustomerList)
DECLARE #Counter INT = 0
DECLARE #CustToProcess INT
CREATE TABLE #Results(CustomerID INT, [Name] VARCHAR(50), OrderDate1 DATETIME,
OrderDate2 DATETIME, OrderDate3 DATETIME, OrderDate4 DATETIME, OrderDate5 DATETIME,
OrderDate6 DATETIME, OrderDate7 DATETIME, OrderDate8 DATETIME, OrderDate9 DATETIME,
OrderDate10 DATETIME, OrderDate11 DATETIME, OrderDate12 DATETIME)
INSERT INTO #Results(CustomerID, Name) SELECT DISTINCT CustomerID, Name FROM Customer_Table
SELECT ROW_NUMBER() OVER(PARTITION BY c.CustomerID ORDER BY OrderDate) RowNo,
c.CustomerID, c.Name, t.OrderDate INTO #SortedRows
FROM Customer_Table c (NOLOCK) JOIN Order_Table t ON c.CustomerID = t.CustomerID
WHILE #Counter < #Count
BEGIN
SET #Counter += 1
SET #CustToProcess = (SELECT CustomerID FROM #CustomerList WHERE RowNo = #Counter)
PRINT #CustToProcess
SELECT * INTO #RowsForProcessing FROM #SortedRows WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate1 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 1) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate2 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 2) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate3 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 3) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate4 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 4) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate5 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 5) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate6 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 6) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate7 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 7) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate8 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 8) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate9 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 9) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate10 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 10) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate11 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 11) WHERE CustomerID = #CustToProcess
UPDATE #Results SET OrderDate12 = (SELECT OrderDate FROM #RowsForProcessing WHERE Rowno = 12) WHERE CustomerID = #CustToProcess
DROP Table #RowsForProcessing
END
SELECT * FROM #Results
Try this if you use MS SQL Server:
-- 1st, get the number of columns
declare #columnnumber int = 1
select #columnnumber = max(a.count)
from (
select c.cid,c.name, count(o.orderdate) as count
from
customer_table c
join order_table o
on c.cid = o.cid
group by c.cid,c.name)a
print #columnnumber
-- Compose the column names for Pivot
declare #columnname varchar(max) = ''
declare #int int = 1
while #int <= #columnnumber
begin
set #columnname = #columnname + '[date' + cast(#int as varchar(10))+ '],'
set #int = #int + 1
end
set #columnname = '('+left(#columnname,len(#columnname)-1)+')'
print #columnname
--Pivot !!! + Dynamic SQL
declare #str varchar(max)
set #str =
'SELECT *
FROM
(SELECT c.cid,c.name, o.orderdate,concat(''date'',row_number() over (partition by c.cid,c.name order by o.orderdate)) rnk
FROM customer_table c
join order_table o
on c.cid = o.cid) AS s
PIVOT
(
min(s.orderdate)
FOR s.rnk IN '+ #columnname+
' ) AS PivotTable'
print #str
execute (#str)
Please change the column name. I used cid as your customerid.
Output:
cid name date1 date2 date3
12 John 2017-03-04 2017-05-26 2017-12-01
4 Nancy 2017-02-01 NULL NULL
Like others said, it's in principle impossible (in pure SQL) to generate this not knowing how many orders you have for a single customer.
I like #nikhil-sugandh's answer, it works great if you are OK with having all orders comma-separated in a single column.
If you insist on having multiple columns, you can build on that answer, by replacing LISTAGG with ARRAY_AGG and postprocessing it. It will be MUCH more efficient than e.g. the proposed solution with multiple joins. You can also use ARRAY_SLICE to handle cases when there are more orders than you are prepared for.
Example (note, I added an extra order to demonstrate handling more-than-expected orders
create or replace table customer_table(customerId int, name varchar)
as select * from values
(12,'John'),(4,'Nancy');
create or replace table order_table(orderId int, customerId int, orderDate date)
as select * from values
(1,12,'3/4/2017'),(2,12,'5/26/2017'),(3,12,'12/1/2017'),(4,4,'2/1/2017'),(5,12,'1/1/2019');
with subq as (
select c.customerid, name,
array_agg(orderdate) within group (order by orderdate) as orders
from customer_table c
inner join order_table o on c.customerid = o.customerid
group by c.customerid, c.name
)
select customerid, name,
orders[0]::date AS order1, orders[1]::date AS order2,
array_to_string(array_slice(orders, 2, 999), ' , ') AS overflow
from subq;
------------+-------+------------+------------+-------------------------+
CUSTOMERID | NAME | ORDER1 | ORDER2 | OVERFLOW |
------------+-------+------------+------------+-------------------------+
4 | Nancy | 2017-02-01 | [NULL] | |
12 | John | 2017-03-04 | 2017-05-26 | 2017-12-01 , 2019-01-01 |
------------+-------+------------+------------+-------------------------+
first create a view like this:
create view order_view as
select
count(*) over (partition by customerId order by orderDate) as ord,
CustomerId,
orderdate
from order_table
then you can use this query:
select c.customerid,
o1.orderdate,
o2.orderdate
o3.orderdate
.
.
.
o12.orderdate
from customer_table c
left join order_view o1
on c.customerid = o1.customerid and ord = 1
left join order_view o2
on c.customerid = o2.customerid and ord = 2
left join order_view o3
on c.customerid = o3.customerid and ord = 3
.
.
.
left join order_view o12
on c.customerid = o12.customerid and ord = 12

ambigious column name in sql server

hello i'm having a ambiguous column name in m stored procedure for payment .bid-id can someone help to resolve this issue please?
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [PaymentID] ASC
)AS RowNumber
,[PaymentID]
,[Name]
,[WinningPrice]
,[PaymentDate]
,[Payment.BidID]
INTO #Results
FROM Item INNER JOIN
Auction ON Item.ItemID = Auction.ItemID INNER JOIN
BID ON Auction.AuctionID = BID.AuctionID INNER JOIN
Payment ON BID.BidID = Payment.BidID
Where (BID.Status = 'Paid') AND (BID.BuyerID = #buyer)
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
End
There is a column name you use in the query that is available in multiple tables.
Without the table structure we can't be certain which one it is, but probably one with an alias in your query:
,[PaymentID]
,[Name]
,[WinningPrice]
,[PaymentDate]
Try this, Create a alias for ambiguous column name
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [PaymentID] ASC
)AS RowNumber
,[PaymentID]
,[Name]
,[WinningPrice]
,[PaymentDate]
,[Payment.BidID] as PBidID
INTO #Results
FROM Item INNER JOIN
Auction ON Item.ItemID = Auction.ItemID INNER JOIN
BID ON Auction.AuctionID = BID.AuctionID INNER JOIN
Payment ON BID.BidID = Payment.BidID
Where (BID.Status = 'Paid') AND (BID.BuyerID = #buyer)
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
End
Good practice is using aliases like:
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY i.[PaymentID] ASC --which table it belongs? put correct alias
)AS RowNumber
,i.[PaymentID]
,i.[Name]
,i.[WinningPrice]
,i.[PaymentDate]
,p.[BidID]
INTO #Results
FROM Item i
INNER JOIN Auction a
ON i.ItemID = a.ItemID
INNER JOIN BID b
ON a.AuctionID = b.AuctionID
INNER JOIN Payment p
ON b.BidID = p.BidID
Where (b.Status = 'Paid')
AND (b.BuyerID = #buyer)
SELECT #RecordCount = COUNT(*)
FROM #Results
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [PaymentID] ASC
)AS RowNumber
,[PaymentID]
,[Name]
,[WinningPrice]
,[PaymentDate]
,[Payment.BidID]
INTO #Results
FROM Item INNER JOIN
Auction ON Item.ItemID = Auction.ItemID INNER JOIN
BID ON Auction.AuctionID = BID.AuctionID INNER JOIN
**Payment P1 ON BID.BidID = P1.BidID**
Where (BID.Status = 'Paid') AND (BID.BuyerID = #buyer)
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
End
Hope this helps..
highlighted the line which i changed

How to set the out parameter when using ROW_NUMBER() & COUNT(*)

How can I set the out #Total parameter of this tsql proc when using the ROW_NUMBER() OVER along with COUNT(*)?
ALTER proc [Generic].[proc_GetPartsForUser_BySupplier_ByCategory]
#UserID UNIQUEIDENTIFIER,
#SupplierID INT,
#CategoryID INT,
#StartIndex INT,
#PageSize INT,
#Total INT out
AS
SET NOCOUNT ON;
SET #StartIndex = #StartIndex + 1
BEGIN
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY ID ASC) AS RowNum, COUNT(*) OVER() AS Total
FROM (
SELECT p.*,
s.Name'SupplierName',s.Email'SupplierEmail',s.Phone'SupplierPhone'
FROM [Generic].[Part] p WITH(NOLOCK) JOIN
Generic.Supplier s WITH(NOLOCK) ON p.SupplierID = s.ID
WHERE p.ID IN(SELECT up.PartID FROM Generic.GenericCatalog gc with(nolock) JOIN
Generic.UserPart up WITH(NOLOCK) ON up.GenericCatID = gc.ID
WHERE gc.UserID = #UserID)
AND
CategoryID = #CategoryID
AND
s.ID = #SupplierID
) AS firstt
) AS final
WHERE RowNum BETWEEN #StartIndex AND (#StartIndex + #pageSize) - 1
ORDER BY final.[Name] ASC;
END;
SET NOCOUNT OFF;
The simple answer is you can't!
The OVER() clause creates a windowed function, meaning it will return the value for every row! The parameter can only store one value!
The question remains, why do you want to do this?
If the point of the entire query is to return the value of COUNT(*), then just use it without the OVER clause like this:
SELECT #Total = COUNT(*)
FROM (SELECT p.*,
s.NAME 'SupplierName',
s.EMAIL'SupplierEmail',
s.PHONE'SupplierPhone'
FROM [Generic].[PART] p WITH(NOLOCK)
JOIN GENERIC.SUPPLIER s WITH(NOLOCK)
ON p.SUPPLIERID = s.ID
WHERE p.ID IN(SELECT up.PARTID
FROM GENERIC.GENERICCATALOG gc WITH(NOLOCK)
JOIN GENERIC.USERPART up WITH(NOLOCK)
ON up.GENERICCATID = gc.ID
WHERE gc.USERID = #UserID)
AND CATEGORYID = #CategoryID
AND s.ID = #SupplierID) AS firstt
If what you need is more than this, edit your question and I'll try to find you a better answer.

Trigger, SQL SERVER 2008

i have two tables
PaymentData
Ser Customerid Totalpaid
1. AGP001 2400
2. AGP002 1000
3. AGP003 1500
Receipt
Receipt# Customerid Paid
1. AGP001 1200
2. AGP001 1200
I want to create a trigger on Receipt table, and trigger will fire on insert, update, and delete operations which updates the totalpaid field of PaymentData table. Everytime a new Receipt record is inserted or updated against some customerid, totalpaid field for that customer will updated as well.
Trigger should do following.
Update PaymentData.totalpaid = sum(Recipt.paid)
where Receipt.customerID = PaymentData.customerID
I guess you need some trigger like:
CREATE TRIGGER dbo.OnReceiptUpdate
ON dbo.Receipt
AFTER INSERT,DELETE,UPDATE --operations you want trigger to fire on
AS
BEGIN
SET NOCOUNT ON;
DECLARE #customer_id VARCHAR(10)
SET #customer_id= COALESCE
(
(SELECT customer_id FROM inserted), --table inserted contains inserted rows (or new updated rows)
(SELECT customer_id FROM deleted) --table deleted contains deleted rows
)
DECLARE #total_paid DECIMAL
SET #total_paid =
(
SELECT SUM(paid)
FROM Receipt
WHERE customer_id = #customer_id
)
UPDATE PaymentData
SET total_paid = #total_paid
WHERE customer_id = #customer_id
IF ##ROWCOUNT = 0 --if nothing was updated - you don't have record in PaymentData, so make it
INSERT INTO PaymentData (customer_id, total_paid)
VALUES (#customer_id, #total_paid)
END
GO
Keep in mind - it aint gonna work with multiply updates/deletes/inserts - This is just example of how you need to do it
Try this trigger with multiply updates, inserts or deletes.
CREATE TRIGGER [dbo].upd_PaymentData ON dbo.Receipt
FOR INSERT, UPDATE, DELETE
AS
IF ##ROWCOUNT = 0 return
SET NOCOUNT ON;
DECLARE #actionTable nvarchar( 10),
#insCount int = (SELECT COUNT(*) FROM inserted),
#delCount int = (SELECT COUNT(*) FROM deleted)
SELECT #actionTable = CASE WHEN #insCount > #delCount THEN 'inserted'
WHEN #insCount < #delCount THEN 'deleted' ELSE 'updated' END
IF #actionTable IN ('inserted', 'updated')
BEGIN
;WITH cte AS
(
SELECT r.Customerid, SUM(r.Paid) AS NewTotalPaid
FROM dbo.Receipt r
WHERE r.Customerid IN (SELECT i.Customerid FROM inserted i)
GROUP BY r.Customerid
)
UPDATE p
SET p.Totalpaid = c.NewTotalPaid
FROM dbo.PaymentData p JOIN cte c ON p.Customerid = c.Customerid
END
ELSE
BEGIN
;WITH cte AS
(
SELECT d.Customerid, SUM(ISNULL(r.Paid, 0)) AS NewTotalPaid
FROM deleted d LEFT JOIN dbo.Receipt r ON d.Customerid = r.Customerid
GROUP BY d.Customerid
)
UPDATE p
SET p.Totalpaid = c.NewTotalPaid
FROM dbo.PaymentData p JOIN cte c ON p.Customerid = c.Customerid
END
CREATE TRIGGER [dbo].upd_PaymentData ON dbo.Receipt
FOR INSERT, UPDATE, DELETE
AS
IF ##ROWCOUNT = 0 return
SET NOCOUNT ON;
DECLARE #actionTable nvarchar( 10),
#insCount int = (SELECT COUNT(*) FROM inserted),
#delCount int = (SELECT COUNT(*) FROM deleted)
SELECT #actionTable = CASE WHEN #insCount > #delCount THEN 'inserted'
WHEN #insCount < #delCount THEN 'deleted' ELSE 'updated' END
IF #actionTable IN ('inserted', 'updated')
BEGIN
;WITH cte AS
(
SELECT r.Customerid, SUM(r.Paid) AS NewTotalPaid,<strike> r.paymentDate</strike>
FROM dbo.Receipt r
WHERE r.Customerid IN (SELECT i.Customerid FROM inserted i)
GROUP BY r.Customerid
)
UPDATE p
SET p.Totalpaid = c.NewTotalPaid
<strike>SET p.lastpaymentDate = c.paymentDate</strike>
FROM dbo.PaymentData p JOIN cte c ON p.Customerid = c.Customerid
END
ELSE
BEGIN
;WITH cte AS
(
SELECT d.Customerid, SUM(ISNULL(r.Paid, 0)) AS NewTotalPaid
FROM deleted d LEFT JOIN dbo.Receipt r ON d.Customerid = r.Customerid
GROUP BY d.Customerid
)
UPDATE p
SET p.Totalpaid = c.NewTotalPaid
FROM dbo.PaymentData p JOIN cte c ON p.Customerid = c.Customerid
END
I tried to add more functionality as indicated inside tage but it gives error and is not working.
Simply added one field in both tables.
In paymentdata added lastpaymentdate,
And in receipt added paymentdate.
On inserting or updating receipt table, paymentdata.lastpaymentdate should also update to receipt.paymentdate.