2013-06-28 56 views
1

這是我之前查詢的後續問題。我希望發佈一個新的問題是恰當的:Selecting a subset of rows from a PHP table使用MySql選擇行的子集:有條件地限制所選條目的數量

我有一個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行。抱歉!

回答

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; 
+0

這這樣做,有非常輕微的mods,以適應我的粗心(見編輯)。謝謝! – KBriggs

+0

歡迎您來到這裏! – Abubakkar

0

您可能需要GROUP BY賣家柱的加入之外。此外,您的WHERE子句看起來像價格是一個設定的數字,而不是<=

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; 

的......這類作品:)

+1

非常感謝您向我介紹使用SQL小提琴!極大的幫助! – KBriggs

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; 
+0

你的第一個查詢幾乎完全是我想要的。我現在意識到我說錯了這個問題。您的查詢完全符合我在OP中詢問的內容,但我所問的並不是我想要的。這種變化是我只希望賣家在全球最低價格下返回的行數,而不是每個賣家的最低價格。所以我實際上從OP的例子中得到的只是第2行或第3行。我的道歉。我正在嘗試修改您的示例,因爲我們說話,結果混雜:) – KBriggs

0

查詢:

SQLFIDDLEExample

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 |