当前位置: 首页 > 面试题库 >

JOIN返回重复项后的GROUP或DISTINCT

莫河
2023-03-14
问题内容

我有两个表,productsmeta。它们之间的关系为1:N,其中每个产品行都通过外键具有至少一个元行。

(即SQLfiddle:http
://sqlfiddle.com/#!15/c8f34/1 )

我需要加入这两个表,但是我只需要过滤唯一的产品。当我尝试此查询时,一切正常(返回4行):

SELECT DISTINCT(product_id)
FROM meta JOIN products ON products.id = meta.product_id

但是当我尝试选择所有列时,DISTINCT规则不再适用于结果,因为返回的是8行而不是4行。

SELECT DISTINCT(product_id), *
FROM meta JOIN products ON products.id = meta.product_id

我尝试了很多方法,例如尝试DISTINCTGROUP BY对子查询进行尝试,但总是得到相同的结果。


问题答案:

虽然检索全部或大部分行从表中,对于这种类型的查询最快的方法通常是聚合/歧义 第一 和加入

SELECT *
FROM   products p
JOIN  (
   SELECT DISTINCT ON (product_id) *
   FROM   meta
   ORDER  BY product_id, id DESC
   ) m ON m.product_id = p.id;

meta每行中的行越多products,对性能的影响越大。

当然,您需要ORDER BY在子查询中添加一个子句,以定义从子查询中的每个集合中选择 哪一
行。@Craig和@Clodoaldo已经告诉过您。我将返回meta最高的行id

SQL提琴。

优化性能

尽管如此,这并不总是最快的解决方案。根据数据分布,还有其他各种查询样式。对于涉及另一个联接的这种简单情况,在带有大表的测试中,该联接的运行速度大大提高:

SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM  (
   SELECT product_id, max(id) AS meta_id
   FROM   meta
   GROUP  BY 1
   ) sub
JOIN meta     m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;

如果您不将非描述性id名称用作列名,那么我们就不会遇到命名冲突,只需编写即可SELECT p.*, m.*。(我 从来没有
使用id的列名。)

如果性能是您的首要要求,请考虑更多选择:

  • 如果您的数据没有变化(很多),则其中MATERIALIZED VIEW包含来自的预汇总数据meta
  • 递归CTE,模拟对每个产品有 很多 行的 表的 松散索引扫描 (相对而言,很少有不同的)。 这是我知道对整个表的DISTINCT查询使用索引的唯一方法。 meta product_id


 类似资料:
  • 我正在编写一个简单的Spring Data JPA应用程序。我使用MySQL数据库。有两个简单的表: 部门 每个员工都在某个部门工作(employee.department\u id)。 方法返回一个包含重复部门的列表(每个部门重复的次数与该部门中的员工一样多)。 问题1:我是否正确地认为这是一个与Spring Data JPA无关但与Hibernate有关的功能? 问题2:修复它的最佳方法是什么

  • 我遇到了一个类似于将多个表中的数据合并到单行中的问题,同时连接一些值,但我不能理解它,而且我是sql查询的新手。我有很少的表,我必须将它们连接起来,并在一行中得到一些串联的数据。说明如下: 而我运行的查询是: 这个查询的结果是: 我不明白为什么名字和电子邮件是重复的?请帮我解决这个问题,也请你解释一下我在概念上哪里出了问题? 我注意到,当与任务关联的类别数超过一个时,就会出现这个问题。请查看htt

  • 我购买了一张桌子,DDL为: Purchase表与purchaseproduct有一对多关系,purchaseproduct的DDL为: 以下是我的POJO: 购买:@Entity@Table(name=“Purchase”)@Access(AccessType.Property)公共类购买{private LongProperty IDPurchase;private StringPropert

  • 问题内容: 我相信这是一件非常简单的事情,我发誓我以前做过,但是我不记得怎么做。 假设我有一对多的关系。我想加入两个表,但不允许左侧表重复。 SQLFIDDLE 因此,根据上述SQLFiddle,我的结果将是: 我希望它是: 我的理由是,通过这种方式,我可以轻松地遍历结果,而无需使用PHP进行任何进一步处理。 问题答案: 您可以将值替换为以下内容: 参见带有演示的SQL Fiddle 结果是:

  • 我在PHP函数中遇到了一个问题,因为对真/假输入的验证不正确 我在这里找到了一个解决方案,那就是采用filter\u var以布尔值进行转换,并检查输入是否有效 制作了一个简单的测试页面和php函数进行尝试;该函数在确定“true,1,on”值时是正确的,并返回正确的“1” 提交“0,false”时,函数不会按预期返回“0”;实际上,它什么也不返回(即使dump_var说它是bool) 这是简单的

  • 问题内容: 我有一个由以下映射的关联: 我想使用Criteria API返回所有包含一个或多个带有attribute实体的实体的列表。我不希望映射集合被查询过滤。 例如,给出以下内容: 该查询应返回以下内容: 到目前为止,我正在使用以下条件查询: 然而,它返回的等价于 即,它为每个子元素返回一个父记录(填充了子集合) 有谁知道在这种情况下如何仅返回唯一的父元素? 意见表示赞赏,p。 问题答案: 您