2013-04-16 37 views
9

我试图从订单中获取订单。在我看来,我确实有一些具有完全相同值的行,但是我想将这些值分组在orderid上并获取该订单数量的总和。SQL Server - GROUP BY上的一列

我的观点的结果是这样的:

Order_id Customer_id Article_id Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a  17-04-2013  1 
PR10.001 11   20.001a  17-04-2013  1 
PR10.001 11   20.001a  17-04-2013  1 
PR13.001 15   41.022b  19-04-2013  1 
PR13.001 15   41.022b  19-04-2013  1 

我想要做的事,如:

SELECT Order_id, Customer_id Article_id, Delivery_date, sum(Quantity) 
FROM Orders 
GROUP BY Order_id 

要得到的东西,如:

Order_id Customer_id Article_id Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a  17-04-2013  3 
PR13.001 15   41.022b  19-04-2013  2 

但我知道一个单一的分组列是不可能的,否则你会得到消息:

在选择列表中无效,因为它不包含在 集合函数或GROUP BY子句中。

是否有另一种可能性或解决方法是按SQL Server中的一个特定列进行分组?

+0

对不起,有什么错我的例子中,我editted它,它应该是现在 – Jovano

回答

14

你可以使用一个CTESUM(Quantity)OVER(PARTITION BY Order_id) + ROW_NUMBER从订单组挑选出所需的行:

WITH cte 
    AS (SELECT order_id, 
       customer_id, 
       article_id, 
       delivery_date, 
       quantity=Sum(quantity) 
          OVER( 
          partition BY order_id), 
       rn = Row_number() 
         OVER( 
         partition BY order_id 
         ORDER BY delivery_date ASC) 
     FROM orders) 
SELECT order_id, 
     customer_id, 
     article_id, 
     delivery_date, 
     quantity 
FROM cte 
WHERE rn = 1 

DEMO

然而,你期望的结果似乎是不正确 (问题编辑)

这是我的结果:

ORDER_ID CUSTOMER_ID ARTICLE_ID DELIVERY_DATE QUANTITY 
PR10.001 11   20.001a   17-04-2013 3 
PR13.001 15   41.022b   19-04-2013 2 
+0

似乎像ARTICLE_ID可以是每个ORDER_ID的倍数,在上面的CTE样本中第一次被挑选出来,并不是一个完整的结果。 – harsh

+0

@harsh:OP并没有提到他也希望通过文章分组,所以我把它留在原地。否则,他可以简单地将ARTICLE_ID添加到“PARTITION BY”。 –

+0

首先:Tim是对的,不需要按Article_id分组,因为每个订单只有1种文章。其次,多么可怕且复杂的解决方法,就好像您曾经使用过MySQL一样,只需使用1组即可,但现在它工作得很好!所有学分给你,谢谢! – Jovano

10

假设其他列在功能上依赖于分组列,最简单的答案是要么

一个。由其他列组,以及:

SELECT Order_id, Customer_id, Article_id, Delivery_date, sum(Quantity) 
FROM Orders 
GROUP BY Order_id, Customer_id, Article_id, Delivery_date 

湾使用聚合函数,如max

SELECT Order_id, max(Customer_id), max(Article_id), max(Delivery_date), sum(Quantity) 
FROM Orders 
GROUP BY Order_id 

我个人的偏好是第二种方法,因为我觉得它比第一个更清晰的指示哪些项目实际需要进行分组,而不是其仅仅被分组以解决未分组/未整理的列问题。

+0

那是我的逻辑也是如此,但清楚,当我尝试做出新的看法,我得到一些新的问题:在你的第一个解决方案中,我得到:“除了使用IS NULL或LIKE运算符时,文本,ntext和图像数据类型不能被比较或排序,”应该是由我的示例中没有包含的某些列引起。你的第二个不会工作,因为我有一些varchar列不支持max() – Jovano

+0

@JorikvanOnna:我希望varchar列始终支持'max',但不一定是文本,ntext或图像数据类型。由于这似乎是您问题的根本原因,因此我建议更新您的问题以包含此信息。蒂姆的答案应该有效,即使有这个限制;另一种方法是按分组列进行分组,并将聚合值包含在内联视图/ CTE中,然后加入到包含问题列的其他表中 - 这将需要更多信息。 –

0

在您的方案中,按照具有不同Article_id的Order_id进行组合似乎不正确。你预计结果看起来不对。它应该是:

PR10.001有两个ARTICLE_ID 20.001a,41.022b和总量4(不是3)

是您的期望是让每个ORDER_ID总量却保留不同列过,那么你需要决定预期的结果?像这样:

Order_id Customer_id Article_id   Delivery_date Quantity 
--------------------------------------------------------------------------- 
PR10.001 11   20.001a, 41.022b  17-04-2013  4 
PR13.001 15   41.022b    19-04-2013  2 
+0

我的预期结果确实是错的,但我编辑它,应该是现在 – Jovano

0

我已经使用类似的表作为你的。名字将是不同的jsu快速测试它。 请参考以下查询。根据需要修改名称。

select ordid,customerid,articleid,SUM(cast(quantity as numeric)) quantity from test_stack group by ordid,customerid,articleid 
0
WITH CTE

AS(SELECT ORDER_ID, CUSTOMER_ID, 的article_id, DELIVERY_DATE, 量= SUM(数量) OVER( PARTITION BY ORDER_ID) RN = ROW_NUMBER() OVER( 分区BY order_id ORDER BY delivery_date ASC) FROM orders) SELECT order_id, customer_id, article_id, DELIVERY_DATE, 数量 FROM CTE 其中RN = 1