表名是“OrderDetails”,列如下:
OrderDetailID || ProductID || ProductName || OrderQuantity
我正在尝试选择多个列和Group By ProductID,同时使用OrderQuantity的SUM。
Select ProductID,ProductName,OrderQuantity Sum(OrderQuantity)
from OrderDetails Group By ProductID
但当然这段代码会出错。我必须添加其他列名称到分组,但这不是我想要的,因为我的数据有很多项目,所以结果是出乎意料的。
示例数据查询:
ProductDetails中的ProductID,ProductName,OrderQuantity
结果如下:
ProductID ProductName OrderQuantity
1001 abc 5
1002 abc 23 (ProductNames can be same)
2002 xyz 8
3004 ytp 15
4001 aze 19
1001 abc 7 (2nd row of same ProductID)
预期结果:
ProductID ProductName OrderQuantity
1001 abc 12 (group by productID while summing)
1002 abc 23
2002 xyz 8
3004 ytp 15
4001 aze 19
如何选择多列和Group By ProductID列,因为ProductName不是唯一的?
这样做时,也可以得到OrderQuantity列的总和。
答案 0 :(得分:45)
当我选择多列时,我使用此技巧分组一列:
lst <- list(blue = blue, Turq = Turq, Indigo = Indigo)
lst
# $blue
# [1] "Ti" "Ka" "Vv" "Cn"
# $Turq
# [1] "Cc" "Wx" "Oq" "Yt"
# $Indigo
# [1] "Gb" "Ap"
stack(lst)
# values ind
#1 Ti blue
#2 Ka blue
#3 Vv blue
#4 Cn blue
#5 Cc Turq
#6 Wx Turq
#7 Oq Turq
#8 Yt Turq
#9 Gb Indigo
#10 Ap Indigo
这很有效。
答案 1 :(得分:10)
您的数据
DECLARE @OrderDetails TABLE
(ProductID INT,ProductName VARCHAR(10), OrderQuantity INT)
INSERT INTO @OrderDetails VALUES
(1001,'abc',5),(1002,'abc',23),(2002,'xyz',8),
(3004,'ytp',15),(4001,'aze',19),(1001,'abc',7)
<强>查询强>
Select ProductID, ProductName, Sum(OrderQuantity) AS Total
from @OrderDetails
Group By ProductID, ProductName ORDER BY ProductID
<强>结果强>
╔═══════════╦═════════════╦═══════╗
║ ProductID ║ ProductName ║ Total ║
╠═══════════╬═════════════╬═══════╣
║ 1001 ║ abc ║ 12 ║
║ 1002 ║ abc ║ 23 ║
║ 2002 ║ xyz ║ 8 ║
║ 3004 ║ ytp ║ 15 ║
║ 4001 ║ aze ║ 19 ║
╚═══════════╩═════════════╩═══════╝
答案 2 :(得分:4)
你可以试试这个:
Select ProductID,ProductName,Sum(OrderQuantity)
from OrderDetails Group By ProductID, ProductName
您只需要Group By
子句中没有聚合函数的Select
列。因此,在这种情况下,您只能使用Group By
ProductID和ProductName。
答案 3 :(得分:2)
WITH CTE_SUM AS (
SELECT ProductID, Sum(OrderQuantity) AS TotalOrderQuantity
FROM OrderDetails GROUP BY ProductID
)
SELECT DISTINCT OrderDetails.ProductID, OrderDetails.ProductName, OrderDetails.OrderQuantity,CTE_SUM.TotalOrderQuantity
FROM
OrderDetails INNER JOIN CTE_SUM
ON OrderDetails.ProductID = CTE_SUM.ProductID
请检查一下是否有效。
答案 4 :(得分:1)
== EDIT ==
我再次检查了你的问题并得出结论,这是不可能的。
ProductName不是唯一的,它必须是Group By
的一部分或从您的结果中排除。
例如,如果Group By
只有ProductID?
ProductID | ProductName | OrderQuantity
---------------------------------------
1234 | abc | 1
1234 | def | 1
1234 | ghi | 1
1234 | jkl | 1
答案 5 :(得分:1)
mysql GROUP_CONCAT
函数可以帮助https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat
SELECT ProductID, GROUP_CONCAT(DISTINCT ProductName) as Names, SUM(OrderQuantity)
FROM OrderDetails GROUP BY ProductID
这将返回:
ProductID Names OrderQuantity
1001 red 5
1002 red,black 6
1003 orange 8
1004 black,orange 15
与@Urs Marian的想法类似的想法在这里发布了https://stackoverflow.com/a/38779277/906265
答案 6 :(得分:1)
在我看来,这是一个严重的语言缺陷,使SQL比其他语言落后几年。这是我难以置信的hack解决方法。这是一个总的麻烦,但总能奏效。
在我开始之前,我想提请注意@Peter Mortensen的答案,我认为这是正确的答案。我之所以执行以下操作的唯一原因是,由于大多数SQL实现的连接操作都异常缓慢,并迫使您中断“不要重复自己”操作。我需要快速填充查询内容。
这也是一种古老的做事方式。 STRING_AGG和STRING_SPLIT更加干净。我再次这样做是因为它始终有效。
-- remember Substring is 1 indexed, not 0 indexed
SELECT ProductId
, SUBSTRING (
MAX(enc.pnameANDoq), 1, CHARINDEX(';', MAX(enc.pnameANDoq)) - 1
) AS ProductName
, SUM ( CAST ( SUBSTRING (
MAX(enc.pnameAndoq), CHARINDEX(';', MAX(enc.pnameANDoq)) + 1, 9999
) AS INT ) ) AS OrderQuantity
FROM (
SELECT CONCAT (ProductName, ';', CAST(OrderQuantity AS VARCHAR(10)))
AS pnameANDoq, ProductID
FROM OrderDetails
) enc
GROUP BY ProductId
或用简明语言:
在性能方面,我一直使用字符串优于bigints之类的字符串。至少使用microsoft和oracle子字符串是一种快速操作。
这避免了在使用MAX()时遇到的问题,当您在多个字段上使用MAX()时,它们不再一致并且来自不同的行。在这种情况下,可以保证您的数据完全按照您要求的方式粘在一起。
要访问第3或第4个字段,您需要嵌套的子字符串,“在第一个分号后寻找第二个”。这就是为什么STRING_SPLIT更好的原因。
注意:虽然超出了您的问题范围,但是当您处于相反的情况并且要对组合键进行分组时,这尤其有用,但是您不希望显示所有可能的排列,也就是说,您想公开' foo”和“ bar”作为组合键,但要按“ foo”分组
答案 7 :(得分:1)
我有与OP类似的问题。然后,我看到了@Urs Marian的回答,这很有帮助。 但是此外,我一直在寻找的是,当一列中有多个值并将它们分组时,如何获取上次提交的值(例如,按日期/ ID列排序)。
示例:
我们具有以下表格结构:
CREATE TABLE tablename(
[msgid] [int] NOT NULL,
[userid] [int] NOT NULL,
[username] [varchar](70) NOT NULL,
[message] [varchar](5000) NOT NULL
)
现在表中至少有两个数据集:
+-------+--------+----------+---------+
| msgid | userid | username | message |
+-------+--------+----------+---------+
| 1 | 1 | userA | hello |
| 2 | 1 | userB | world |
+-------+--------+----------+---------+
因此,如果相同的用户标识具有不同的用户名值,则以下SQL脚本确实可以工作(在MSSQL上已选中)以对其进行分组。在下面的示例中,将显示具有最高msgid的用户名:
SELECT m.userid,
(select top 1 username from table where userid = m.userid order by msgid desc) as username,
count(*) as messages
FROM tablename m
GROUP BY m.userid
ORDER BY count(*) DESC
答案 8 :(得分:0)
您可以尝试以下查询。我假设您的所有数据都有一个表格。
SELECT OD.ProductID, OD.ProductName, CalQ.OrderQuantity
FROM (SELECT DISTINCT ProductID, ProductName
FROM OrderDetails) OD
INNER JOIN (SELECT ProductID, OrderQuantity SUM(OrderQuantity)
FROM OrderDetails
GROUP BY ProductID) CalQ
ON CalQ.ProductID = OD.ProductID
答案 9 :(得分:0)
我只是想添加一种更有效,更通用的方式来解决此类问题。 主要思想是使用子查询。
按分组依据,并在表的ID上加入相同的表。
您的情况更具体,因为您的productId不是不唯一,因此有两种解决方法。
我将从更具体的解决方案开始:
由于您的productId 不是唯一,因此,我们需要执行一个额外的步骤,即在对分组进行分组并进行子查询后选择DISCTINCT
产品ID,如下所示:
WITH CTE_TEST AS (SELECT productId, SUM(OrderQuantity) Total
FROM OrderDetails
GROUP BY productId)
SELECT DISTINCT(OrderDetails.ProductID), OrderDetails.ProductName, CTE_TEST.Total
FROM OrderDetails
INNER JOIN CTE_TEST ON CTE_TEST.ProductID = OrderDetails.ProductID
这完全返回了预期的结果
ProductID ProductName Total
1001 abc 12
1002 abc 23
2002 xyz 8
3004 ytp 15
4001 aze 19
但是,这里有一种更简洁的方法。我猜想ProductId
是产品表的外键,并且我猜该表中应该有OrderId
主键(唯一)。
在这种情况下,仅对一个分组时,只需执行几个步骤即可包括多余的列。将与以下相同解决方案
让我们以这个t_Value
表为例:
如果我想按描述分组并显示所有列。
我要做的就是:
WITH CTE_Name
子查询INNER JOIN
在ID( 主键或唯一约束 )列上具有CTE 就是这样!
这是查询
WITH CTE_TEST AS (SELECT Description, MAX(Id) specID, COUNT(Description) quantity
FROM sch_dta.t_value
GROUP BY Description)
SELECT sch_dta.t_Value.*, CTE_TEST.quantity
FROM sch_dta.t_Value
INNER JOIN CTE_TEST ON CTE_TEST.specID = sch_dta.t_Value.Id
结果如下:
希望这会有所帮助!
HK
答案 10 :(得分:-3)
SELECT ProductID, ProductName, OrderQuantity, SUM(OrderQuantity) FROM OrderDetails WHERE(OrderQuantity) IN(SELECT SUM(OrderQuantity) FROM OrderDetails GROUP BY OrderDetails) GROUP BY ProductID, ProductName, OrderQuantity;
我使用上述解决方案来解决Oracle12c中的类似问题。