【问题标题】:WHERE clause gives different result wether in subquery or notWHERE 子句是否在子查询中给出不同的结果
【发布时间】:2018-03-26 16:45:05
【问题描述】:

关注最后两行...

SELECT *
FROM
  (SELECT d.*
   FROM downloads AS d
   LEFT JOIN ps_customer AS pc ON d.id_customer=pc.id_customer
   WHERE pc.active=1
     AND d.id_customer IS NOT NULL
   GROUP BY id_product,
            id_customer) AS tmp
WHERE YEAR(tmp.date_download)=2015
  AND tmp.name='Antescofo'

and(移动到子查询中)

SELECT *
FROM
  (SELECT d.*
   FROM downloads AS d
   LEFT JOIN ps_customer AS pc ON d.id_customer=pc.id_customer
   WHERE pc.active=1
     AND d.id_customer IS NOT NULL
     AND YEAR(d.date_download)=2015
     AND d.name='Antescofo'
   GROUP BY id_product,
            id_customer) AS tmp

...给出不同的行数结果。

我试图理解为什么,因为 WHERE 子句在某种程度上起到了过滤器的作用。

在子查询中或之后过滤有什么区别?

在我的理解中,第一个类似于 “选择所有来自现有和活跃客户的重复数据下载,并仅显示 2015 年生产的 Antescofo 产品的下载”

第二个类似“从现有的和活跃的客户中选择所有与 Antescofo 产品相关并在 2015 年制作的重复数据下载,并显示所有内容”

【问题讨论】:

  • 问题:为什么要在这两种情况下都使用子查询?似乎您正在增加复杂性而没有任何好处。如果 group by 中包含的行的 date_download 列具有不同的值,则分组行中的值会有所不同,并且可能不是您所期望的。
  • 补充一下@SloanThrasher 所说的,您对 LEFT JOIN 的使用也有点毫无意义,WHERE pc.active = 1 将其变成了 INNER JOIN。

标签: mysql sql syntax


【解决方案1】:

当您引用不在group by 列表中的列时,MySQL 将从组中的一行中返回一个随机选择的值。因此,无论您是在子查询内部、group by 之前进行过滤,还是在子查询外部、group by 之后进行过滤,这都很重要。在第二种情况下,将随机包含或排除具有匹配行和不匹配行的组。

【讨论】:

    【解决方案2】:

    当您像这样移动 where 子句时,您正在过滤不同的内容。在第一个查询中,您正在过滤分组结果;在第二个中,您对过滤结果进行分组。最重要的是,在第一个中,您正在过滤一个未分组、未聚合的字段;许多风格的 SQL 和 MySQL 当前的默认配置甚至不允许这样的(子)查询。第一个查询基本上是从分组的每个id_product, id_customer 组合的值中随机选择的值进行过滤。

    【讨论】:

      猜你喜欢
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2012-01-31
      • 2018-09-12
      • 1970-01-01
      • 2015-12-17
      • 2013-12-30
      相关资源
      最近更新 更多