带有 2 个表的 SQL Server GROUP BY

Posted

技术标签:

【中文标题】带有 2 个表的 SQL Server GROUP BY【英文标题】:SQL Server GROUP BY with 2 tables 【发布时间】:2021-08-15 16:31:13 【问题描述】:

我想知道如何创建这个 GROUP BY 子句,这里有 2 个表:

一个订单可以有多个车辆通过Order.Id => OrderVehicle.OrderId 链接到它。 我想要存档的是创建一个查询,该查询将检测可能的订单重复并收到错误,因为我使用Order.Id 列链接到OrderVehicle.OrderId 列,这是我的尝试:

SELECT
    COUNT(1) AS [Total],
    CAST(o.[CreatedOn] AS DATE),
    o.[Amount],
    o.[OrderTypeId]
FROM
    [dbo].[Order] o
GROUP BY
    CAST(o.[CreatedOn] AS DATE),
    o.[Amount],
    o.[OrderTypeId]
HAVING COUNT(1) > 1;

这个查询应该找到相同数量的订单([Order].[Amount]),在同一天创建([Order].[CreatedOn]),是相同的订单类型([Order].[OrderTypeId]),并且存在这样的> 1 (HAVING COUNT(1) > 1)。

上述查询按原样工作,如果此[Order].[OrderTypeId] 是用户可以选择车辆的地方,我需要在订单中包含订单车辆时出现问题。我希望存档的是结合[dbo].[OrderVehicle].[VehicleId],例如在子选择中连接它,例如如果 Order.Id 25 链接到 3 OrderVehicles 则 Group By 子句必须 CONCAT [dbo].[OrderVehicle].[VehicleId] 列上的 3 OrderVehicles

这可能吗,如果可以,我该如何归档这样的内容?或者我应该以不同的方式解决这个问题?感谢并提前非常感谢。

【问题讨论】:

请提供示例数据和表结构 您可以使用 Partition By 来做到这一点。使用windows函数比使用Having和groups更好 谢谢大家,我会测试这两种解决方案,看看它是否对我有帮助 @Tyron78 我已经用表格结构更新了问题 @Morgs 我编辑了我的答案。我只用了两张桌子。我正在为您提供完成工作的逻辑。您可以根据您的要求加入任意数量的表格。看看,如果您需要任何帮助,请告诉我 :) 很乐意提供帮助 【参考方案1】:

我建议在 Vehicles 表上创建一个 CTE,它使用 XMP PATH 来连接您的 Vehicle 列表。一个例子:

DECLARE @tOrderVehicle TABLE(
ID int, OrderID int, VehicleID int
)

INSERT INTO @tOrderVehicle VALUES
(1, 1, 1)
,(2, 1, 2)
,(3, 1, 3)
,(4, 2, 1)
,(5, 2, 4)
,(6, 3, 1)
,(7, 3, 2)
,(8, 3, 3)


;WITH cteOrderVehicles AS(
select OrderID, STUFF(
        (SELECT  ',' + CAST(a.VehicleID AS VARCHAR(100))  AS [text()]
        from @tOrderVehicle  a
        where a.OrderID = b.OrderID
        Order by a.VehicleID
        for xml PATH('')),1,1,''       ) AS Vehicles_Concatenated
 from @tOrderVehicle b
group by b.OrderID
)
SELECT *
  FROM cteOrderVehicles
ORDER BY OrderID

如果您将此加入您的订单表,您应该也可以考虑您组中的车辆。

【讨论】:

【参考方案2】:

我想建议你使用 windows 功能。有了这个,这很简单。你可以很容易地得到你的结果。 Row_Number() 用于从最终结果中过滤掉重复的分区。

  CREATE TABLE [order] 
  (
  id INT
  ,amount INT
  ,[OrderTypeId] int 
   )

 create table vehicleOrder
 (
 id int primary key
 ,order_id int
 ,createdOn DATE
 ,vehicleId int    
  )

INSERT INTO [order] VALUES(1,200000, 1)
 ,(2,40000, 1)
 ,(3,2006000, 1)
 ,(4,56777,3)
 ,(5,145887, 4)
 ,(2,40000, 1)
 ,(3,2006000, 1)
  ,(1,200000, 1)

 INSERT INTO vehicleOrder VALUES(1,1,'02/05/2016',200000)
 ,(2,1,'02/05/2016',40000)
 ,(3,2,'02/06/2016',2006000)
 ,(4,1,'02/06/2016',56777)
 ,(5,3,'07/06/2016',145887)
 ,(6,2,'02/05/2016',40000)
 ,(7,3,'02/06/2016',2006000)
 ,(8,1,'02/05/2016',200000)


 SELECT *
 FROM
  (
      SELECT
        ROW_NUMBER() OVER (PARTITION BY   CAST(vo.[CreatedOn] AS DATE) ,  o.[Amount],    o.[OrderTypeId] ORDER BY  vo.[CreatedOn] ) as [rn] 
        , COUNT(1) OVER (PARTITION BY   CAST(vo.[CreatedOn] AS DATE) ,  o.[Amount],    o.[OrderTypeId] ORDER BY   vo.[CreatedOn] ) as [Count]
        ,  CAST(vo.[CreatedOn] AS DATE) [CreatedOn]
        , o.[Amount]
        , o.[OrderTypeId]

     FROM   [order]   o 
     INNER JOIN  vehicleOrder vo 
        ON O.id = vo.order_id
  ) AS A 
  WHERE A.[Count] > 1 AND A.rn = 1

我正在给你逻辑,如何通过基于分区来获得聚合。多列。

【讨论】:

我尝试了您的解决方案,但看起来您混淆了列。 AmountOrderTypeId 位于 Order 表中,而不是 OrderVehicle 表中,因此当我尝试时您的解决方案无法运行...我将使用 2 个表的 SQL 图表更新问题 我的回答是基于您之前发布的内容。为了您的方便,我将对其进行编辑并发布,@Morgs 您可以从派生表中选择您想要的任何列。我选择了所有列。 @Morgs 感谢您推荐的解决方案 @Morgs 让我知道需要的任何支持。很高兴为您提供帮助!

以上是关于带有 2 个表的 SQL Server GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章

用于 4 个表的 SQL Server 2008 连接类型

视图中四个表的 SQL Server 条件连接

sql2005 中的把2个表创建成一个视图

sql server 触发器 从一个表添加到另个表是否两个表对应的字段必须相同呢

带有管理工作室的 MS SQL Server - 如何使用其数据(作为插入语句)编写表的脚本? [复制]

将基表值与第二个表的值之和与group by进行比较