1

这是我之前查询的后续问题。我希望在这种情况下发布一个新问题是合适的:Selecting a subset of rows from a PHP table

我有一个看起来像这样的 sql 表(例如):

id seller price amount
1  tom    350   500
2  tom    350   750
3  tom    350   750
4  tom    370   850
5  jerry  500   1000

我想为每个卖家选择一行:特别是对于每个卖家,我想要价格最便宜的行,并且在该价格下数量最多。在上面的示例中,我想要第 2 行和第 5 行(或第 3 行和第 5 行,只要我只得到其中一个,我不在乎得到 2 和 3 中的哪一个)。

我正在使用这个:

dbquery("SELECT a.* FROM $marketdb a
        INNER JOIN
        (
            SELECT  seller, MAX(amount) amount
            FROM    $marketdb
            WHERE   price=$minprice
            GROUP   BY seller
        ) b ON a.seller = b.seller AND
                a.amount = b.amount;");

但这给了我第 2,3 和 5 行,我只想要第 2 和第 3 行之一。

我也有一个挥之不去的怀疑,这也可能并不总是返回最低价格行。到目前为止,我的测试一直被这样一个事实所迷惑,即我为给定的卖家输入了不止一行的相同金额。

如果有人能指出我的错误,我将不胜感激。

谢谢!

编辑:对不起,我没有问我的意思。我希望从全球最低价格返回的行,每个卖家最多 1 个,而不是每个卖家的最低价格。这将只是上面的第 2 行或第 3 行。对不起!

4

5 回答 5

2

只需尝试在卖家上添加另一个组,因为您想要为卖家提供单行

到最终查询

SELECT a.* FROM $marketdb a
INNER JOIN
(
    SELECT  seller, MAX(amount) amount
    FROM    $marketdb
    WHERE   price=$minprice
    GROUP   BY seller
) 
b ON a.seller = b.seller AND
a.amount = b.amount group by a.seller;
于 2013-06-28T17:19:09.607 回答
1

测试这个SQL 小提琴

http://sqlfiddle.com/#!2/7de03/2/0

CREATE TABLE `sellers` (
  `id` INT UNSIGNED  NOT NULL AUTO_INCREMENT,
  `seller` VARCHAR(16) NOT NULL,
  `price` FLOAT NOT NULL,
  `amount` INT UNSIGNED NOT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO `sellers` VALUES (1, 'tom', 350, 500);
INSERT INTO `sellers` VALUES (2, 'tom', 350, 750);
INSERT INTO `sellers` VALUES (3, 'tom', 350, 750);
INSERT INTO `sellers` VALUES (4, 'tom', 350, 850);
INSERT INTO `sellers` VALUES (5, 'jerry', 500, 600);
INSERT INTO `sellers` VALUES (6, 'jerry', 500, 1000);
INSERT INTO `sellers` VALUES (7, 'jerry', 500, 800);

SELECT * FROM
(SELECT DISTINCT * FROM sellers ORDER BY price ASC, amount DESC) t0
GROUP BY seller;

有点......工作:)

于 2013-06-28T17:37:03.003 回答
1

这个答案的末尾有一个丑陋的黑客,但如果你不关心返回哪一行,那么我想它可以节省一些打字。虽然,如果您真的不在乎返回哪一行,那往往表明您的架构设计存在更根本的缺陷!

 SELECT x.* 
   FROM market x 
   JOIN 
      ( SELECT seller,MIN(price) min_price FROM market GROUP BY seller) y 
     ON y.seller = x.seller 
    AND y.min_price = x.price
   JOIN 
      ( SELECT seller,price,MAX(amount) max_amount FROM market GROUP BY seller,price) z
     ON z.seller = y.seller 
    AND y.min_price = z.price
    AND z.max_amount = x.amount
  GROUP
     BY seller;   

另一种我不喜欢但在这里受到其他人欢迎的方法是这样的......

SELECT x.*         
  FROM 
     ( SELECT * 
         FROM market
        ORDER
           BY seller
            , price
            , amount DESC
            , id
     ) x
 GROUP
    BY seller;
于 2013-06-28T17:40:42.637 回答
0

你可能需要GROUP BY在卖家栏之外加入。此外,您的WHERE子句看起来像 price 是一个设定数字,而不是<=.

于 2013-06-28T17:20:00.283 回答
0

询问:

SQLFIDDLE示例

SELECT s.* 
FROM sellers s 
WHERE s.id = (SELECT s2.id
              FROM sellers s2
              WHERE s2.seller = s.seller
              ORDER BY s2.price ASC, s2.amount DESC
              LIMIT 1)

结果:

| ID | SELLER | PRICE | AMOUNT |
--------------------------------
|  2 |    tom |   350 |    750 |
|  5 |  jerry |   500 |   1000 |
于 2013-06-28T18:07:57.690 回答