英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论