Hi Team
I have duplicate record from my table, reason being i notice its because there is more than one FarmName with different CustomerName uses same tripsheetno that is why its doing that. How can i restrict this so there could be unique trip sheet number per each FarmName?
USE [Batcher]
GO
/****** Object: StoredProcedure [dbo].[GetTripWeightReport] Script Date: 2024/04/30 15:19:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetTripWeightReport] --'2024-04-24', '2024-04-25'
(
@StartDate Date, @EndDate Date
)
AS
BEGIN
SELECT DISTINCT
t.TripsheetNo,
t.ProductWeight AS 'TripSheetReport Weight'
,
cu.Customer,
f.FarmID
INTO #FINISHEDPRODUCT
FROM [dbo].[Tripsheet] t
LEFT JOIN [dbo].[WeighbridgeTicket] wt ON t.TripsheetNo = wt.trip
LEFT JOIN [dbo].[Customer] cu ON cu.CustomerID = wt.CustomerID
LEFT JOIN [dbo].[Farm] f ON f.FarmID = cu.Farmid
WHERE
CONVERT(DATE, t.Tripdate, 103) BETWEEN @StartDate AND @EndDate And topseal <> '' and bottomseal <> ''
SELECT DISTINCT *
INTO #SALES
FROM
(
SELECT DISTINCT
ProdDay = CASE
WHEN CAST(WT.LoadedTime AS Time) > '00:00:00' AND CAST(WT.LoadedTime AS Time) < '06:00:00'
THEN DATEADD(day, -1, Convert(DATE, WT.LoadedDate, 103))
ELSE Convert(DATE, WT.LoadedDate, 103)
END,
tps.TripsheetNo,
CASE
WHEN tps.TripsheetNo = 229080 AND WT.LoadedDate = @StartDate THEN 28020
ELSE SUM(tk.productweight)
END AS 'SalesReport Weight',
WT.LoadedTime,
WT.LoadedDate
FROM [Batcher].[dbo].[Tripsheet] tps
INNER JOIN [Batcher].[dbo].[WeighbridgeTicket] tk on tps.tripsheetno = tk.trip
LEFT JOIN (
SELECT trip,
LoadedDate = MIN(WeighTime),
LoadedTime = SUBSTRING(CONVERT(VARCHAR, MIN(Weightime), 108),12,8)
FROM [Batcher].[dbo].[WeighbridgeTicket]
WHERE Compartment <> 'truck-empty'
GROUP BY trip
) WT on tk.trip = WT.trip
LEFT JOIN Batcher.dbo.TripReturnRedelivery TRR ON TRR.Ticket = TK.ticketnumber
WHERE tk.productweight > 0
GROUP BY
CASE
WHEN CAST(WT.LoadedTime AS Time) > '00:00:00' AND CAST(WT.LoadedTime AS Time) < '06:00:00'
THEN DATEADD(day, -1, Convert(DATE, WT.LoadedDate, 103))
ELSE Convert(DATE, WT.LoadedDate, 103)
END,
tps.TripsheetNo,
WT.LoadedTime,
WT.LoadedDate
) Core
WHERE CONVERT(datetime, Core.LoadedDate, 103) BETWEEN @StartDate AND @EndDate;
SELECT DISTINCT
s.ProdDay,
s.Tripsheetno,
s.[SalesReport Weight],
ISNULL(cu.Customer, '') as Customer,
ISNULL(f.FarmID, '') as FarmName,
ISNULL(f.[TripSheetReport Weight], 0) as [TripSheetReport Weight],
ISNULL(f.[TripSheetReport Weight], 0) - s.[SalesReport Weight] AS Discrepancy,
CASE
WHEN ISNULL(f.[TripSheetReport Weight], 0) != s.[SalesReport Weight] THEN 'Warning'
WHEN s.[SalesReport Weight] = f.[TripSheetReport Weight] THEN 'PASS'
END AS ErrorWarning
FROM #SALES s
LEFT JOIN #FINISHEDPRODUCT f ON s.Tripsheetno = f.TripsheetNo
LEFT JOIN [dbo].[Customer] cu ON cu.CustomerID = cu.CustomerID
LEFT JOIN [dbo].[Farm] fa ON f.FarmID = cu.Farmid
END
Naimish MakwanaPosted May 2, 2024, 8:50 AM
To ensure that each
FarmNamehas a uniqueTripsheetNo, you can add a unique constraint or unique index on theTripsheetNoandFarmNamein yourTripsheettable. This will prevent any new records from being inserted that would result in a duplicateTripsheetNofor the sameFarmName.However, before you can add this constraint, you will need to deal with any existing duplicates in your data. You can identify these with a query like:
Once you have dealt with the duplicates (for example, by deleting or modifying the duplicate rows), you can add the unique constraint:
This will ensure that you cannot have more than one
FarmNamewith the sameTripsheetNo. Please note that this is a significant change to your database schema, so you should make sure to backup your data before proceeding, and thoroughly test your application afterwards to ensure there are no unforeseen side effects.Also, please note that this solution assumes that
TripsheetNoandFarmNameare columns in yourTripsheettable. If they are not, you will need to adjust the queries accordingly. IfFarmNameis not stored directly in theTripsheettable and is only accessible via a join, then the situation is more complex and might require changes to your application logic. In such a case, you might need to handle this in your application code to check for duplicates before inserting new records.Thanks
Jayraj ChhayaPosted May 2, 2024, 7:44 AM
Hi Gcobani Mkontwana,
Try below solution
Guest UserPosted May 2, 2024, 7:03 AM
Hi All
I have modified the query for both answers, but somehow this still give me same output as before.
Jayraj ChhayaPosted May 2, 2024, 6:27 AM
Hi,
Problem
Upon analyzing the code, I have identified the following issues that may be causing the bug:
The temporary tables "#FINISHEDPRODUCT" and "#SALES" are being created with the "SELECT DISTINCT *" statement. This can lead to unexpected results if there are duplicate rows in the underlying data.
The join condition between the "#FINISHEDPRODUCT" and "#SALES" tables is using the "TripsheetNo" column. If there are duplicate "TripsheetNo" values in either table, it can result in incorrect data being joined.
The join condition between the "#FINISHEDPRODUCT" table and the "Customer" and "Farm" tables is using the wrong column names. It should be "cu.CustomerID" instead of "cu.CustomerID" and "fa.FarmID" instead of "f.FarmID".
Solution
To fix the bug and improve the code, I recommend the following solutions:
Instead of using the "SELECT DISTINCT *" statement, explicitly specify the columns needed for the temporary tables "#FINISHEDPRODUCT" and "#SALES". This will ensure that only the necessary columns are selected and eliminate any duplicate rows.
Modify the join condition between the "#FINISHEDPRODUCT" and "#SALES" tables to include additional columns that uniquely identify a trip. For example, you can include the "FarmID" column from the "#FINISHEDPRODUCT" table and the "ProdDay" column from the "#SALES" table in the join condition.
Correct the join condition between the "#FINISHEDPRODUCT" table and the "Customer" and "Farm" tables by using the correct column names. Replace "cu.CustomerID" with "cu.CustomerID" and "f.FarmID" with "fa.FarmID".
Here's the modified code with the suggested fixes:
Jithu ThomasPosted May 2, 2024, 6:18 AM
The provided stored procedure has duplicate records because it doesn't enforce uniqueness on the
TripsheetNowithin eachFarmName1. Modify the
#FINISHEDPRODUCTSelection:Instead of
SELECT DISTINCT, useSELECT TOP 1 WITH TIESin the first section where you populate the#FINISHEDPRODUCTtemporary table. This ensures you only get one record perTripsheetNofor eachFarmName, prioritizing the record with non-emptytopsealandbottomsealvalues.Here's the modified code:
2. No Need for Additional Filtering in
#SALES:The filtering logic within the subquery for
#SALESalready accounts for handling weights loaded before 6 AM on the current date by usingDATEADD(day, -1). You can remove the additional filtering based on@StartDateandTripsheetNo=229080in theCASEstatement.3. Update the Final
SELECTStatement:The final
SELECTstatement uses the temporary tables to join data. No changes are needed here.With these modifications, the stored procedure will ensure unique
TripsheetNoperFarmNamein the#FINISHEDPRODUCTtable, leading to accurate discrepancy calculations in the final result set.