如何编写“每组最大n”类型查询,但附加条件?

时间:2012-03-23 14:35:33

标签: mysql greatest-n-per-group

我提出了一个关于昨天制作“每组最大n”类型查询的问题(当时不知道它被称为“每组最大n”),除了我问如何获得每组最少。表格结构如下:

type    name    value
=====================
1       item1    1
1       item2    20
2       item3    0
3       item4    5
3       item5    2
3       item6    50

我收到了几个很好的答案,最有帮助的是:

SELECT t1.type, t1.name, t1.value
FROM mytable t1
LEFT JOIN mytable t2 ON t1.type = t2.type AND t1.value > t2.value
WHERE t2.value IS NULL

以上查询结果如下:

type    name    value
=====================
2       item3    0
1       item1    1
3       item5    2

然而,自从提出问题以来,我意识到我遗漏了一个重要的要求,我似乎无法弄清楚如何添加到上面的查询。我需要添加一个条件语句,该条件语句不是选择每个列的列值最小的行,而是选择每个组的列值最小的行,但是该行的另一个列的值更大比一些最小值。

这是我的新问题/问题:


我有下表(产品):

+-----------------------------------------------------------+
|   id   |   type   |   name   |   popularity   |   price   |
+-----------------------------------------------------------+
|    0   |    0     |   item1  |      3.5       |   0.99    |
|    3   |    1     |   item2  |      3         |   1.99    |
|    4   |    1     |   item3  |      6         |   2.95    |
|    6   |    1     |   item4  |      9         |   2.50    |
|    9   |    1     |   item5  |      12        |   3.75    |
|    12  |    2     |   item6  |      16        |   5.25    |
|    13  |    2     |   item7  |      32        |   10.95   |
|    14  |    2     |   item8  |      48        |   7.50    |
+-----------------------------------------------------------+

我需要获得每个组中价格最低的项目(组是不同的类型值),其受欢迎程度大于某个数量(如果组中没有项目的人气超过指定数量,则没有项目从该组返回)。该句的最后一部分是这个问题与我上一个问题的不同之处。优选地,结果应按价格按升序排序。

所以,说流行度需要大于3,那么结果应该是:

+-----------------------------------------------------------+
|   id   |   type   |   name   |   popularity   |   price   |
+-----------------------------------------------------------+
|    0   |    0     |   item1  |      3.5       |   0.99    |
|    6   |    1     |   item4  |      9         |   2.50    |
|    12  |    2     |   item6  |      16        |   5.25    |
+-----------------------------------------------------------+

如果受欢迎程度需要大于6,则结果应为:

+-----------------------------------------------------------+
|   id   |   type   |   name   |   popularity   |   price   |
+-----------------------------------------------------------+
|    6   |    1     |   item4  |      9         |   2.50    |
|    12  |    2     |   item6  |      16        |   5.25    |
+-----------------------------------------------------------+

希望我能正确地完成这两个例子。无论如何,我认为你明白了。

可以在一个查询中执行我要求的操作吗?

1 个答案:

答案 0 :(得分:4)

这需要注意将条件放到哪里(到whereon?)以便不被欺骗:-)你需要将t1的条件添加到{{ 1}}子句和t2到where子句:

on

没有测试过,但它应该可以工作。

尝试解释: where子句中的条件会影响您认为哪些元素具有最低值的潜在元素。而SELECT t1.type, t1.name, t1.value FROM mytable t1 LEFT JOIN mytable t2 ON t1.type = t2.type AND t1.value > t2.value AND t2.popularity > 3 /* here */ WHERE t2.value IS NULL AND t1.popularity > 3 /* and here */ 子句中的条件会影响链接:您要比较哪些其他元素?它定义了您比较的组。从技术上讲,它对t2。*将为NULL时有影响。如果您将t2.popularity的条件改为on子句,那么对于最低元素具有较低流行度的组,您将不会收到任何NULL(即找不到具有最低值的元素)。