【问题标题】:Sql group by with very large join alternative具有非常大的连接替代方案的 Sql group by
【发布时间】:2016-09-07 20:40:44
【问题描述】:

表 1

Itemid   saleid
---------------
53355    23224
33544    33246
53355    33353
43324    33353

表 2

Saleid  Rebate
--------------
23224    3000
33246    5000
33353    5555
33353    4444

这是一个简化的表格。我遇到的问题是我想先按 itemid 分组,然后加入 table2 saleid。如果我自己按 saleid 分组,它会返回 100,000 行数据,这很好,但如果我也按 saleid 分组加入它,我会得到数百万行,这对我来说不可行。有什么想法可以让我完成这项工作,以便我可以连接这些表吗?

所以请记住 itemid 有很多我可以分组的项目,但 saleid 不是唯一的,所以想在分组后连接它

这是一个简单的查询,例如,它可以让我找到数百万行。如果在group by if之后加入的话应该还是100000行数据。

select 
    ta.itemid, ta.saleid, sa.itemid
from 
    table1 ta
inner join 
    saleid sa 
where 
    ta.saleitemid = sa.itemid
group by 
    itemid, saleid

【问题讨论】:

  • 显示实际查询,但很可能您无能为力。你得到的正是你所要求的。请注意,您不会“分组然后加入”。加入首先完成,因为只有在所有相关行数据可用之后才能确定分组。
  • 如果有帮助,我在上面提供了一个简单的查询。
  • 一个商品 ID 可以与多个销售 ID 配对吗?
  • 其实。我们可能还需要按第二个表进行分组,因为它可能与 table2 中的多个销售 ID 配对,但很高兴在第二个问题之前先解决第一个问题。
  • 你想要什么结果集?我希望在聚合查询中看到聚合函数。

标签: sql sql-server


【解决方案1】:

虽然 Group By 可以让您减少查询返回的记录数,但它通常用于聚合(count()、sum()、min()、max() 等)。在 Group By 子句中添加的任何内容都会影响返回的记录数,因为您使 group by 更具体,这会降低其将行分组在一起的能力。

听起来您的 ItemId 表和 SalesId 表之间存在一对多关系。因此,如果您从 Item 表中选择并仅按 ItemId 进行分组,这是一个更通用的分组,并且会将记录计数减少到仅表中那些唯一的 ItemId。如果您将 SalesId 包含在您的分组依据中,那么现在您将仅按 ItemId 和 SalesId 的那些唯一组合进行分组,这将产生更多记录。

此时是否将 SalesId 表加入到此查询中都没有关系,您将始终获得唯一 ItemId 和 SalesId 的数量,只要它们都包含在 Group By 中。

也许可以尝试通过提供有关您查询的数据的更多细节来重申您试图获得的结果,我们可以帮助您编写对性能更友好的选择...

【讨论】:

  • 我想要达到的结果是最初减少 itemID 作为起点,它将有 100k 行,然后附加 salesID(仍然有 100k 行),然后将为我提供表 2 的链接。在表 2 中,我需要使 saleids 独一无二并总结回扣。然后将其附加到表 1,因此总体上我们将有 100k 行,其中包含 itemid、saleid 和 sum(rebate)。这就是我想要实现的目标,我不需要使用 group by,只是想以某种方式让它工作,但是 table1 中的 saleids 和 itemid 的 group by 给了我太多的结果,达到百万。
  • 好的,所以实际上您想要做的聚合是在销售表中汇总回扣值。这是由销售 ID 完成的吗?如果是这样,您应该按销售 ID 对该表中的记录进行分组,并将其加入您对唯一 ItemId/SalesId 组合的查询。如果销售 ID 是您尝试返回的最细粒度级别的数据,请首先将该数据分组到具有总回扣的各个销售 ID。将其加入商品/销售组合不应增加记录数。
  • 是的,这是正确的。聚合在该表中完成。但不知何故需要将它链接到表 1 中的那 100k 行,否则 table1 会变得很大。重要的是,我需要在 table1 中有一个减少的数据集。我遇到的问题是表 1,我希望能够保留减少的记录,然后附加表 2 以获取与 saleid 关联的回扣。只是无法让第一个表 1 工作
  • 我也意识到第一个表问题是对于每个唯一的 itemid 我都有多个 saleid 附加到它。所以我必须按照建议先带上table2以获得回扣。然后只创建一个 itemid 和 rebate 的新表,并按 itemid 分组。对此有何想法?
【解决方案2】:

如果您使用子查询,您可以先进行分组,然后将该查询加入表 2:

SELECT *
FROM
(SELECT itemid, saleid
FROM Table_1
GROUP BY itemid, saleid) sub
INNER JOIN Table_2
ON sub.saleid = Table_2.saleid

编辑:根据您的 cmets,上述查询不适用于您,因此我将尝试提出一个问题,以引导我们找到您真正想要的。

假设这是表1:

Itemid   saleid
20000    23224
33544    33246
53355    22523
43324    33353
43324    11111
43324    22222
43324    33333
43324    44444

这是表 2:

Saleid  Rebate
23224    3000
33246    5000
22523    5555
33353    4444
11111    1111 
22222    2222 
33333    3333
44444    4444

在 cmets 中告诉我们您想要的输出是什么样的。

附加更新:这个显示每个项目 id 的总和(回扣):

SELECT itemid, SUM(rebate)
FROM t1 INNER JOIN t2
ON t1.saleid = t2.saleid
GROUP BY itemid

【讨论】:

  • 问题是,在第一个表中,当您将 saleid 添加到 group by 时,group by 无法正常工作,因为使用 itemid 它通常会分组到 100k 行,但是当您将 group by 扩展到在第一个表中包含 saleid 它扩展为我的整体结果一百万,这不是我需要的。
  • 所以听起来 itemid 可以与多个 saleid 配对。在这种情况下,您是否尝试减少结果集,以便每个 itemid 只匹配一个 saleid?如果是这样,您是否要选择最小或最大 saleid,例如?应该列出哪一个?
  • 嗯,我想做的是按 itemid 将第一个表分组,这将结果减少到 100k,然后对于这 100k 有 saleids。同时表2有多个saleids需要分组。它只是将这些链接到哪个问题。
  • 我意识到第一个表问题是,对于每个唯一的 itemid,我都有多个 saleid 附加到它。因此,我必须按照建议的汇总回扣,首先将 table2 带到 table2 上。然后我认为我需要制作一个新的 itemid 表,并且只回扣 somhhow 并按 itemid 分组作为子集。关于此的任何想法
  • 那么您真正想要的是每个 itemid 的汇总回扣?如果是这样,请参阅上面的补充...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多