【问题标题】:Converting query with aggregate functions to a group by将带有聚合函数的查询转换为 group by
【发布时间】:2014-06-11 11:45:55
【问题描述】:

我要做的是提取客户订购的订单和订单数量。 我能够获取所有数据,但我想要的是根据每个客户唯一的 TrackingID 对其进行分组,因此无论订购多少商品,每个客户只能获得一行。

我目前拥有的代码是

Select OT.TrackingID As FW_ID
,(  Select
    SUBSTRING(CT.Name, 1, CHARINDEX(' ', CT.Name) - 1)
    Where LEN(CT.Name) - LEN(REPLACE(CT.Name, ' ', '')) > 0
)   As Forename
,(  Select
    SUBSTRING(CT.Name, CHARINDEX(' ', CT.Name) + 1, 8000)
    Where LEN(CT.Name) - LEN(REPLACE(CT.Name, ' ', '')) > 0
)   As Surname
,(  Select CAST(1 as VARCHAR) + ' p1 male'  
Where OT.ArticleNr = 1
And CT.GroupNr IN (2,5)) As Amount_male_t1
,(  Select CAST(1 as VARCHAR) + ' p1 female'  
Where OT.ArticleNr = 2
And CT.GroupNr IN (2,5)) As Amount_female_t1
,(  Select CAST(1 as VARCHAR) + ' p2 male'  
Where OT.ArticleNr = 1
And CT.GroupNr IN (3,6)) As Amount_male_t2
,(  Select CAST(1 as VARCHAR) + ' p2 female'  
Where OT.ArticleNr = 2
And CT.GroupNr IN (3,6)) As Amount_female_t2

From OrderTable As OT
JOIN CustomerTable As CT
    ON OT.CustomerNr = CT.CustomerNr
JOIN CampaignTable As CT
    ON OT.TrackingID = CT.TrackingID
Where CT.GroupNr IN (2,3,5,6)
And OT.NewOrder = 1

我可以从中得到的一个例子是

FW_ID      Forename      Surname      Amount_male_t1      Amount_female_t1      Amount_male_t2      Amount_female_t2
101        John          Doe          1 p1 male           NULL                  NULL                NULL
101        John          Doe          NULL                1 p1 female           NULL                NULL
102        Steve         Boss         NULL                NULL                  1 p2 male           NULL
102        Steve         Boss         NULL                NULL                  1 p2 male           NULL

而我想要的是

FW_ID      Forename      Surname      Amount_male_t1      Amount_female_t1      Amount_male_t2      Amount_female_t2
101        John          Doe          1 p1 male           1 p1 female           NULL                NULL
102        Steve         Boss         NULL                NULL                  2 p2 male           NULL

问题是,当我在 OT.TrackingID 上使用 Group By 时,我在名称上使用 MAX() 时出现错误,因为它们已经聚合,并且在尝试将包计数器转换为 COUNT() 函数时出错。 非常感谢您的帮助。

连接的表看起来像这样

订单表:

TrackingID      CustomerNr      OrderNr      ArticleNr      NewOrder      OrderDate
101             10054           25           1              1             2014-06-09
101             10054           24           2              1             2014-06-09
102             10036           23           1              1             2014-06-08
102             10036           22           1              1             2014-06-07
103             10044           21           2              0             2014-06-06

客户表

CustomerNr      Name          Adress        ZipCode      CustomerCreatedDate
10054           John Doe      Upstreet      123456       2013-05-18
10036           Steve Boss    Downstreet    234567       2014-06-07
10044           Eric Cartman  Sidestreet    345678       2014-02-21

活动表

TrackingID      GroupNr      ProductDescription
101             2            Group 2 & 5 are offered package 1
102             3            Group 3 & 6 are offered package 2
103             5            Group 2 & 5 are offered package 1

注意:如果有人可以就我的问题为何被否决提出建议,那将不胜感激。我不太清楚自己做错了什么。

【问题讨论】:

    标签: sql sql-server group-by aggregate-functions


    【解决方案1】:

    如前所述,一种方法是使用视图。您可以在查询中内联执行此操作,而无需将其保存在架构中。

    我创建了一个demo 来展示如何使用您提供的示例表数据来完成此操作。从这里开始,如果您想将数据的表示更改为单行,您可以将其旋转,如 here 所示。

    SELECT SplitNames.Forename, SplitNames.LastName FROM CustomerTable
    INNER JOIN
    (
      SELECT CustomerNr,
      SUBSTRING(CT.Name, 1, CHARINDEX(' ', CT.Name) - 1) As Forename,
      SUBSTRING(CT.Name, CHARINDEX(' ', CT.Name), LEN(CT.Name) - 1) As LastName
      FROM CustomerTable CT
    ) SplitNames ON CustomerTable.CustomerNr = SplitNames.CustomerNr
    

    一般来说,您应该尝试在 select 语句中使用尽可能少的子查询,因为这会导致无法正确汇总您的任何结果。

    【讨论】:

    • 我用你的小提琴演奏了一下,这帮助我得到了我想要的,所有在一个查询中。谢谢。
    【解决方案2】:

    您可以将查询用作视图,然后使用 distinct 和 count 子句将该视图用于新查询。 对不起,我知道这不是最好的解决方案,因为它有两个步骤,也许可以以更好的方式解决,但目前我找不到更好的解决方案,我的数据库上没有任何示例数据。

    【讨论】:

    • 我不太明白您所说的“作为视图”是什么意思。此外,我更愿意将其保留为单个查询或某种链/嵌套解决方案。
    • 一个 sql 视图是一个虚拟表。 w3school。 CREATE VIEW view_name AS (your code here) SELECT DISTINCT, COUNT(column) FROM view_name GROUP BY column “我希望将其保留为单个查询或某种链/嵌套解决方案。”是的,我明白了。我希望有人会给你一个更好的解决方案。
    • 你试过最后按别名分组吗?只需尝试添加:group by FW_ID 最后,看看会发生什么
    • 是的 Tanner,单独的 Group By 与 Substring funktions 发生冲突。也可以使用子选择。无论如何,虽然这有点乏味,但 insilenzios 的建议最终确实给出了正确的结果,一旦我有了视图,就很容易得到我想要的东西。我应该发布我的最终解决方案还是这个答案足以满足未来的人们?
    • 如果您愿意,可以使用 WITH 子句代替视图。这样将创建一个“运行时视图”。 WITH view_name AS (你的代码在这里) SELECT DISTINCT, COUNT(column) FROM view_name GROUP BY column
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2021-04-20
    相关资源
    最近更新 更多