Reputation: 1412
this is a followup question to my previous query. I hope that posting a new question is appropriate in the circumstances: Selecting a subset of rows from a PHP table
I have an sql table that looks like this (for example):
id seller price amount
1 tom 350 500
2 tom 350 750
3 tom 350 750
4 tom 370 850
5 jerry 500 1000
I want to select one row per seller: in particular, for each seller I want the row with the cheapest price, and the largest amount at that price. In the example above, I want rows 2 and 5 (or 3 and 5, I don't care which of 2 and 3 I get as long as I only get one of them).
I am using this:
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;");
But this is giving me rows 2,3 and 5, and I only want one of rows 2 and 3.
I also have a nagging suspicion that this might not always return the minimum price rows either. My tests so far have been confused by the fact that I am getting more than one row with the same amount entered for a given seller.
If someone could point out my error I would be most appreciative.
Thanks!
EDIT: my apologies, I did not ask what I mean to ask. I would like rows returned from the global min price, max 1 per seller, not the min price for each seller. This would be only row 2 or 3 above. Sorry!
Upvotes: 1
Views: 3632
Reputation: 9724
Query:
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)
Result:
| ID | SELLER | PRICE | AMOUNT |
--------------------------------
| 2 | tom | 350 | 750 |
| 5 | jerry | 500 | 1000 |
Upvotes: 0
Reputation: 15644
Just try adding another group by on seller as you want single row for a seller
to final query like
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;
Upvotes: 2
Reputation: 33935
There's an ugly hack at the end of this answer, but if you don't care which row is returned then I guess it saves some typing. Although, if you really don't care which row is returned, that tends to point to a more fundamental flaw in your schema design!
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;
Another method, which i dislike but which is popular with others here, goes something like this...
SELECT x.*
FROM
( SELECT *
FROM market
ORDER
BY seller
, price
, amount DESC
, id
) x
GROUP
BY seller;
Upvotes: 1
Reputation: 12985
Test this SQL fiddle:
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;
Kind of... works :)
Upvotes: 1
Reputation: 9142
You may need to GROUP BY
the seller column outside of the join. Also, your WHERE
clause looks like where price is a set number, instead of <=
.
Upvotes: 0