SQL Group by和update / delete行

时间:2018-01-30 07:38:33

标签: sql sql-server

我有一个SQL.Table

CREATE TABLE [dbo].[Stack_Example](
    [ID] [bigint] NOT NULL,
    [Product_ID] [bigint] NULL,
    [Quantity] [decimal](18, 2) NULL,
    [Price] [decimal](18, 2) NULL,
 CONSTRAINT [PK_Stack_Example] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

使用如下所示的数据:

INSERT [dbo].[Stack_Example] ([ID], [Product_ID], [Quantity], [Price]) VALUES (1, 25, CAST(55.00 AS Decimal(18, 2)), CAST(1000.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Stack_Example] ([ID], [Product_ID], [Quantity], [Price]) VALUES (2, 25, CAST(1.00 AS Decimal(18, 2)), CAST(1000.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Stack_Example] ([ID], [Product_ID], [Quantity], [Price]) VALUES (3, 26, CAST(1.00 AS Decimal(18, 2)), CAST(500.00 AS Decimal(18, 2)))
GO

所以我的问题是我需要按价格,Product_Id和SUM(数量)对这些项目进行分组。

需要更新/删除查询,假设我的输出窗口需要看起来像

enter image description here

执行选择查询时很简单

select Product_ID,SUM(Quantity) AS Quantity,Price from Stack_Example
Group by Product_ID,Price

所以在开始我需要做的是删除id为2的行并更新id为1的行设置Quantity = Quantity + 1(已删除行的数量)。

因此,当我在没有分组和求和的情况下运行select查询时,我需要获得相同的输出

UPDATE Stack_Example SET Quantity = (SELECT SUM(Quantity)
                                    FROM Stack_Example child 
                                    WHERE child.Product_ID = Stack_Example.Product_ID
                                    GROUP BY Product_ID)

DELETE FROM Stack_Example WHERE ID IN (SELECT TOP 1 ID 
                                        FROM Stack_Example 
                                        WHERE Product_Id IN ( (SELECT TOP 1 Product_ID 
                                                                    FROM Stack_Example
                                                                    GROUP BY Product_ID 
                                                                    HAVING COUNT(Product_ID)>1)))

4 个答案:

答案 0 :(得分:1)

首先使用相同价格的产品总数更新您的表格

with cte as (
    select
        Product_ID, Price, Quantity = sum(Quantity) 
    from
        Stack_Example
    group by Product_ID, Price
)

update s
set s.Quantity = c.Quantity
from
    Stack_Example s
    join cte c on s.Product_ID = c.Product_ID and s.Price = c.Price

然后运行另一个脚本以删除重复的行

with cte as (
    select
        *, row_number() over (partition by Product_ID, Price order by Product_ID) rn
    from
        Stack_Example
)

delete from cte where rn > 1

答案 1 :(得分:0)

我有点不清楚 - 但你不能只用aggrgates创建一个视图吗?

总之..... 不知道为什么你会这样做但是......你可以插入聚合值,然后删除旧的......如下所示。

DECLARE @MaxId INT;
DECLARE @ProductId = 25;


--GET THE MAX ID OF PRODUCT IN QUESTION
SELECT @MaxId = MAX(ID) FROM Stack_Example WHERE Product_Id = @ProductId;


--INSERT THE AGGREGATE VALUES INTO TABLE
INSERT INTO Stack_Example
  SELECT @MaxId + 1, @ProductId, Price, SUM(Quantity)
  FROM Stack_Example
  WHERE 
    Product_Id = @ProductId
  GROUP BY 
    @MaxId + 1, [Product_ID], [Price];

--DELETE THE PRE-AGGREGATE VALUES
DELETE FROM Stack_Example WHERE ProductId = @ProductId and Id <= @MaxId;

答案 2 :(得分:0)

好吧,我使用聚合和额外的临时表来实现:

--group records and insert them into temporary table
select distinct
     Min(id) over (partition by product_id, price) [ID],
     Product_id,
     sum(Quantity) over (partition by product_id, price) [Quantity],
     Price
into #new_stack_example
from #Stack_Example

--delete old values
delete #Stack_example

--insert new values
insert into #Stack_example
select * from #new_stack_example

第一个SELECT语句反映了您的逻辑:

  

所以我的问题是我需要按价格,Product_Id和SUM(数量)对这些项目进行分组。

但我不是分组,而是使用窗口函数,然后选择不同的记录。

答案 3 :(得分:0)

检查一下:

    UPDATE Stack_Example SET Quantity = a.Quantity
    from ( select Product_ID,sum(Quantity) Quantity  
    from Stack_Example Group by Product_ID) a
    where   Stack_Example.Product_ID=a.Product_ID   

    ;with cte as (
    select *,ROW_NUMBER () over (partition by product_id order by product_id) rn 
    from Stack_Example)

    delete from cte where rn > 1