MYSQL - 在保留WHERE语句的同时获取最低列值行

时间:2016-04-30 14:13:28

标签: mysql

我想抓取pathproduct_images的所有positionSELECT pi.product_id, path, position from product_images pi JOIN product_categories pc ON (pc.product_id = pi.product_id) WHERE pc.category_id = 59 GROUP BY pi.product_id ORDER BY pi.position ASC 为1或最接近它(ASC)。

我试图从特定类别中抓取每个产品的第一张产品图片。

这是我的疑问:

order by

对此无效的是,它并不总是抓取位置为1的图像,而是将某些产品放在第2位。

我认为这是因为我group位置category_id | product_id 之后(已经采用随机行)?

如何正确订购?

表格结构:

product_categories

id | product_id | path | position

product_images

gulp.task('injecttest', function () {
    var target = gulp.src('wwwroot/index.html');
    var sources = gulp.src(['wwwroot/app/js/**/*.js'], { read: false });

    return target.pipe(inject(sources, { ignorePath: '/wwwrooot/')).pipe(gulp.dest('wwwroot/'));;
});

1 个答案:

答案 0 :(得分:1)

为什么它不起作用

您需要表product_image中的某些行,但GROUP BY生成的结果不包含表中的行。 GROUP BY计算它返回的值。此外,您在问题中发布的查询是无效的SQL,因为SELECT查询的GROUP BY子句只允许包含这些类型的表达式:

  • 表达式也出现在GROUP BY子句中;
  • 使用GROUP BY aggregate functions;
  • 的表达式
  • 功能上依赖于GROUP BY子句中的列的列。

此处只有查询的pi.product_id子句中的SELECT列才是安全的。如果GROUP BY pi.id,f.e。

,则允许使用其他两列

在版本5.7.5之前,MySQL曾经允许这样的无效查询(而其他RDBMS则拒绝它们)。但是,对于与上述任何规则都不匹配的表达式返回的值为indeterminate。但是你已经发现了(我引用你:“它已经采用了随机行”)。

解决方案

应该生成您需要的结果的查询(我没有测试它)看起来像:

SELECT pi.product_id, pi.path, pi.position
FROM product_categories pc
  INNER JOIN product_images pi         # product image
    ON pi.product_id = pc.product_id
  LEFT JOIN product_images bi          # better image...
    ON bi.product_id = pi.product_id   # ... of the same product
       AND bi.position < pi.position   # ... better because of `position`
WHERE pc.category_id = 59 
  AND bi.id IS NULL         # keep only when there isn't a match in "better image"

如何运作

查询加入product_categories,因为它只需要针对表product_images(别名为pi)选择特定类别的产品图像。这是您在查询中已经拥有的内容,我只是交换了表的顺序,使查询更易于阅读和理解。接下来,它再次加入product_images(别名为bi来自“更好的图片”,就position而言更好。

连接将左表中的每一行(在本例中为pcpi之间的连接)与右表(bi)中的所有行组合在一起。它会将每个产品图片(来自pc JOIN pi)与同一产品中具有更好position的所有图片进行匹配。因为它是LEFT JOIN,所以即使在右表中没有匹配的行,它也会在结果集中放入左表中的所有行。在这种情况下,将使用一行满NULL个值而不是右表中的行。

接下来,WHERE子句仅过滤我们所需类别的产品,更重要的是,只过滤从表NULL中提取的bi部分的行。但这些图像在“更好的图像”表中没有匹配;即他们拥有最好的(最小的)position

最后,SELECT子句包含表pi中所需的列(它还可以包含pc中的列)。无论如何,落在结果集中的表bi中的所有列都是NULL