存储过程以删除重复项但保留一些数据

huangapple go评论70阅读模式
英文:

Stored Procedure to remove duplicates but keep some data

问题

I'll provide the translated code portions as requested:

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
with PCTE AS 
(
SELECT Count(*) as Count, Companies.Id as companyid, Branches.id as branchid, c.name as InventoryCenter
FROM dbo.InventoryItems INNER JOIN
     dbo.inventoryCategories on InventoryItems.inventoryCategoryID = inventoryCategories.id Inner JOIN
     dbo.InventoryCenters c on inventoryCategories.InventoryCenterId = c.Id INNER JOIN
     dbo.Branches ON InventoryItems.BranchId = Branches.Id INNER JOIN
     dbo.Companies ON Branches.CompanyId = Companies.Id
WHERE 
  InventoryItems.Deleted = 'False'AND
  Branches.IsDeleted= 'False' AND
  Companies.IsDeleted = 'False'  AND
  IsShownToMembers = 'True' AND
  Companies.Id = 20 
group by Companies.Id, Branches.id , c.name 
)
, CompanySummaryCTE AS
(
select companyid, branchid, [Part Center], [Equipment Center], [Attachment Center], [Powertrain Center], [Salvage Center] 
    from PCTE
PIVOT (Sum(Count) for InventoryCenter IN ([Part Center], [Equipment Center], [Attachment Center], [Powertrain Center], [Salvage Center] )) as P
)
, cteInvoices AS (
    select t.CompanyId, t.FirstRun, t.NextRun, f.DisplayedAs as Frequency
        , l.Description as InvoiceLineDescription, l.Quantity as InvoiceLineQuantity, l.DiscountAmount as InvoiceLineDiscount
        , l.ServiceId as InvoiceLineServiceId
        from RecurringInvoiceTemplates t
        inner join RecurringInvoiceFrequencies f on t.RecurringInvoiceFrequencyId = f.Id
        inner join RecurringInvoiceLines l on l.RecurringInvoiceTemplateId = t.Id
)
, cteFinal AS (
SELECT Companies.Id as CompanyId, Companies.Name AS CompanyName, p.Name as MembershipType,Branches.Name as BranchName, I.InvoiceLineDescription
FROM   
CompanySummaryCTE cte
JOIN Companies ON cte.companyid = companies.Id
JOIN Branches on Branches.CompanyId = Companies.Id
JOIN CompanyProducts cp on companies.id	= cp.companyid
JOIN Products p on cp.ProductId = p.Id
LEFT JOIN cteInvoices I on Companies.Id = i.CompanyId
where 
Companies.IsDeleted = 0
and Branches.IsDeleted = 0
and p.ProductTypeId = 2
) 

 --Original data with magic numbers added based on partition functions
SELECT DISTINCT * , 
DENSE_RANK() OVER (PARTITION BY BranchName ORDER BY BranchName, InvoiceLineDescription ) DescriptionGroup,
DENSE_RANK() OVER (PARTITION BY InvoiceLineDescription ORDER BY BranchName) BranchGroup
FROM cteFinal
WHERE 1=1
order by CompanyId 

--Insert into 

-- Once you have the magic numbers worked out, just filter out the rows you don't want
SELECT * FROM (
SELECT * , 
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, InvoiceLineDescription ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY InvoiceLineDescription ORDER BY BranchName) BranchGroup
FROM cteFinal
) F
WHERE F.BranchGroup = 1 OR F.DescriptionGroup = 1
--ORDER BY F.BranchName, F.InvoiceLineDescription

END

Please note that this translation may not include specific variables, object names, or database configurations, as requested.

英文:

I am working on SP to help return a list a records to assist with invoicing for certain types of membership...

(I have cut the SP down to work with just one company until I get it going - there will be multiple MembershipType - this example we are using 'Buyer Membership')

So each company will have multiple branches, and each branch will have 3 records relating to the 'invoice line description' which are currently returned on the SP...

InvoiceLineDescription

Branch Monthly Membership
Buyer Monthly Membership
Carrying Charge

like so:

Company                                         Invoice Line
Id     CompanyName   MembershipType  BranchName Description
20     DeluxPainting BuyerMemberShip Branch1  Branch MonthlyMembership
20     DeluxPainting BuyerMemberShip Branch1  Buyer Monthly Membership
20     Deluxainting  BuyerMemberShip Branch1  Carrying Charge
20     DeluxPainting BuyerMemberShip Branch2  Branch MonthlyMembership
20     DeluxPainting BuyerMemberShip Branch2  Buyer Monthly Membership
20     DeluxPainting BuyerMemberShip Branch2  Carrying Charge
20     DeluxPainting BuyerMemberShip Branch3  Branch MonthlyMembership
20     DeluxPainting BuyerMemberShip Branch3  Buyer Monthly Membership
20     DeluxPainting BuyerMemberShip Branch3  Carrying Charge

I want to break this down further...

So only returning one instance of
'Buyer Monthly Membership',(for each company)

1 instance of 'Carrying Charge'(for each company)

and then list 'Branch Monthly Membership' for each different branch

So the above data should change to

Company                                         Invoice Line
Id     CompanyName   MembershipType  BranchName Description
20     DeluxPainting BuyerMemberShip Branch1  Buyer Monthly Membership
20     Deluxainting  BuyerMemberShip Branch1  Carrying Charge
20     DeluxPainting BuyerMemberShip Branch1  Branch MonthlyMembership
20     DeluxPainting BuyerMemberShip Branch2  Branch MonthlyMembership
20     DeluxPainting BuyerMemberShip Branch3  Branch MonthlyMembership

I just cant seem to get over the line for this final request

(removing Buyer Monthly Membership & Carrying Charge for branch 2 and 3)

Is this even possible?

Any help please?

UPDATE
Thank you for helping me with this... I added in what you suggested and it worked for the first part showing DescriptionGroup and BranchGroup but the second select however is flagging with cteFinal - invalid object name.(your @T) Do I need to declare it globally or how can I get it to use the results?

I tried to put it into a temp variable but then just copied the contents of the SP over to a new table and was able to do a simple select statment...but I would like to get it working as you have shown in your exmaple.. please could you suggest how I can fix the below...

 BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
with PCTE AS 
(
SELECT  Count(*) as Count, Companies.Id as companyid, Branches.id as branchid, c.name as InventoryCenter
FROM            dbo.InventoryItems INNER JOIN
dbo.inventoryCategories on InventoryItems.inventoryCategoryID = inventoryCategories.id Inner JOIN
dbo.InventoryCenters c on inventoryCategories.InventoryCenterId = c.Id INNER JOIN
dbo.Branches ON InventoryItems.BranchId = Branches.Id INNER JOIN
dbo.Companies ON Branches.CompanyId = Companies.Id
WHERE 
InventoryItems.Deleted = 'False'AND
Branches.IsDeleted= 'False' AND
Companies.IsDeleted = 'False'  AND
IsShownToMembers = 'True' AND
Companies.Id = 20 
group by Companies.Id, Branches.id , c.name 
)
, CompanySummaryCTE AS
(
select companyid, branchid, [Part Center], [Equipment Center], [Attachment Center], [Powertrain Center], [Salvage Center] 
from PCTE
PIVOT (Sum(Count) for InventoryCenter IN ([Part Center], [Equipment Center], [Attachment Center], [Powertrain Center], [Salvage Center] )) as P
)
, cteInvoices AS (
select t.CompanyId, t.FirstRun, t.NextRun, f.DisplayedAs as Frequency
, l.Description as InvoiceLineDescription, l.Quantity as InvoiceLineQuantity, l.DiscountAmount as InvoiceLineDiscount
, l.ServiceId as InvoiceLineServiceId
from RecurringInvoiceTemplates t
inner join RecurringInvoiceFrequencies f on t.RecurringInvoiceFrequencyId = f.Id
inner join RecurringInvoiceLines l on l.RecurringInvoiceTemplateId = t.Id
)
, cteFinal AS (
SELECT Companies.Id as CompanyId, Companies.Name AS CompanyName, p.Name as MembershipType,Branches.Name as BranchName, I.InvoiceLineDescription
FROM   
CompanySummaryCTE cte
JOIN Companies ON cte.companyid = companies.Id
JOIN Branches on Branches.CompanyId = Companies.Id
JOIN CompanyProducts cp on companies.id	= cp.companyid
JOIN Products p on cp.ProductId = p.Id
LEFT JOIN cteInvoices I on Companies.Id = i.CompanyId
where 
Companies.IsDeleted = 0
and Branches.IsDeleted = 0
and p.ProductTypeId = 2
) 
--Original data with magic numbers added based on partition functions
SELECT DISTINCT * , 
DENSE_RANK() OVER (PARTITION BY BranchName ORDER BY BranchName, InvoiceLineDescription ) DescriptionGroup,
DENSE_RANK() OVER (PARTITION BY InvoiceLineDescription ORDER BY BranchName) BranchGroup
FROM cteFinal
WHERE 1=1
order by CompanyId 
--Insert into 
-- Once you have the magic numbers worked out, just filter out the rows you don't want
SELECT * FROM (
SELECT * , 
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, InvoiceLineDescription ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY InvoiceLineDescription ORDER BY BranchName) BranchGroup
FROM cteFinal
) F
WHERE F.BranchGroup = 1 OR F.DescriptionGroup = 1
--ORDER BY F.BranchName, F.InvoiceLineDescription
END

答案1

得分: 1

以下是已翻译的内容:

这是类似于您所寻找的东西。使用这种方法,您可以将分组简化为更简单的表达式。这适用于您的特定情况,但您可能需要调整它以适应您的实际数据,包括为要保留在其他分支中的“Description”添加标识符。在此逻辑中,它只保留最后一个字母顺序的描述。

-- 请注意,在您的问题中提供此类数据可以加快答案速度
DECLARE
@T TABLE (ID INT, CompanyName VARCHAR(100), MembershipType VARCHAR(100), BranchName VARCHAR(100), Description VARCHAR(100))

INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Carrying Charge')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Carrying Charge')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Carrying Charge')

-- A. Original data with magic numbers added based on partition functions
-- THIS IS FOR ILLUSTRATION ONLY. It is not needed for the final answer
SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, Description ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY Description ORDER BY BranchName) BranchGroup
FROM @T

-- B. Once you have the magic numbers worked out, just filter out the rows you don't want
SELECT * FROM (
SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, Description ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY Description ORDER BY BranchName) BranchGroup
FROM @T
) F
WHERE F.BranchGroup = 1 OR F.DescriptionGroup = 1
ORDER BY F.BranchName, F.Description

英文:

Here is something like what you area after. Using this approch you boil grouping down into much simpler expressions. This works for your particaular case but you'll likely need to fiddle with it for your real data, including adding an identifier for which "Description" you want to keep for remaining branches. In this logic, it just keeps the last alphabetical one.

-- Note that providing data like this in your question speeds up the answer
DECLARE 
@T TABLE (ID INT, CompanyName VARCHAR(100), MembershipType VARCHAR(100), BranchName VARCHAR(100), Description VARCHAR(100))
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch1','Carrying Charge')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch2','Carrying Charge')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Branch MonthlyMembership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Buyer Monthly Membership')
INSERT INTO @T VALUES(20,'DeluxPainting','BuyerMemberShip','Branch3','Carrying Charge')
-- A. Original data with magic numbers added based on partition functions
-- THIS IS FOR ILLUSTRATION ONLY. It is not needed for the final answer
SELECT * , 
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, Description ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY Description ORDER BY BranchName) BranchGroup
FROM @T
-- B. Once you have the magic numbers worked out, just filter out the rows you don't want
SELECT * FROM (
SELECT * , 
ROW_NUMBER() OVER (PARTITION BY BranchName ORDER BY BranchName, Description ) DescriptionGroup,
ROW_NUMBER() OVER (PARTITION BY Description ORDER BY BranchName) BranchGroup
FROM @T
) F
WHERE F.BranchGroup = 1 OR F.DescriptionGroup = 1
ORDER BY F.BranchName, F.Description

huangapple
  • 本文由 发表于 2023年6月13日 10:23:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461354.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定