SQL - selecting all rows with maximum value

2020-07-10 06:49发布

I have this SQL query:

SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
      JOIN tt
      ON st.id = tt.id
GROUP BY id;

Now, I want to select all rows which have the maximum price of the table. I have tried this, which unfortunately returns no row at all:

SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
      JOIN tt
      ON st.id = tt.id
GROUP BY id
HAVING price = MAX(price);

I'm somewhat lost, does anybody have any pointers?

6条回答
不美不萌又怎样
2楼-- · 2020-07-10 07:29

Assuming that @Zane's answer is what you do want, here's a portable version of his query that also avoids LIMIT/TOP operations. I'm not really familiar with mysql dialects, but I imagine this will work without problem.

SELECT a.id, a.price
FROM (
    SELECT aa.id, COUNT(1) AS price
    FROM rt aa
    INNER JOIN tt bb ON aa.id = bb.id
    WHERE [somecondition]
    GROUP BY aa.id
) a
WHERE
    a.price >= ALL (
        SELECT COUNT(1) AS maxprice
        FROM rt aa
        INNER JOIN tt bb ON aa.id = bb.id
        WHERE [somecondition]
        GROUP BY aa.id
    )
查看更多
男人必须洒脱
3楼-- · 2020-07-10 07:35

This looks fairly simple to me:

select * from <table> 
where <column name> in(
   SELECT MAX(column name) FROM table
)
查看更多
不美不萌又怎样
4楼-- · 2020-07-10 07:38

Try this solution:

SELECT a.id, a.price
FROM
(
    SELECT aa.id, COUNT(1) AS price
    FROM rt aa
    INNER JOIN tt bb ON aa.id = bb.id
    WHERE aa.somecondition
    GROUP BY aa.id
) a
INNER JOIN
(
    SELECT MAX(aa.price) AS maxprice
    FROM
    (
        SELECT COUNT(1) AS price
        FROM rt aaa
        INNER JOIN tt bbb ON aaa.id = bbb.id
        WHERE aaa.somecondition
        GROUP BY aaa.id
    ) aa
) b ON a.price = b.maxprice

Edit: While I can't think of any way to rewrite this so as to not have to write the base-queries redundantly, what you could perhaps do is this:

SELECT GROUP_CONCAT(a.id) AS ids, a.price
FROM
(
    SELECT aa.id, COUNT(1) AS price
    FROM rt aa
    INNER JOIN tt bb ON aa.id = bb.id
    WHERE aa.somecondition
    GROUP BY aa.id
) a
GROUP BY a.price
ORDER BY a.price DESC
LIMIT 1

This produces a comma-separated-list of the ids that share the same maximum value. This is probably not the format you are looking for though, but it is one way to avoid having to write the base-query twice. Just putting that out there.

查看更多
可以哭但决不认输i
5楼-- · 2020-07-10 07:41

try this, put MAX in select, this should be the correct way

SELECT id, COUNT(*) AS price, MAX(price) AS max_price
FROM (SELECT some_table_name FROM rt WHERE somecondition LIMIT 1) AS st
      JOIN thenextTable as tt
      ON st.id = tt.id
GROUP BY id;
查看更多
做个烂人
6楼-- · 2020-07-10 07:43

HAVING is used to check conditions after the aggregation takes place.

WHERE is used before the aggregation takes place.

SELECT id, COUNT(*) AS price
FROM (SELECT * FROM rt WHERE somecondition) AS st
  JOIN tt
  ON st.id = tt.id
WHERE price = (SELECT MAX(price) FROM ...table)
GROUP BY id
查看更多
虎瘦雄心在
7楼-- · 2020-07-10 07:50

You asked for an approach that didn't require the redundancy of stating the inner query more than once. That's certainly what a cte is good for. These are two other solutions rewritten to use that tactic.

WITH basequery as (
    SELECT aa.id, COUNT(1) AS price
    FROM rt aa INNER JOIN tt bb ON aa.id = bb.id
    WHERE [aa.somecondition]
    GROUP BY aa.id
)
SELECT a.id, a.price
FROM
    basequery as a INNER JOIN
    (SELECT MAX(price) AS maxprice FROM basequery) as b
        ON a.price = b.maxprice
-- or
WITH basequery as (
    SELECT aa.id, COUNT(1) AS price
    FROM rt aa INNER JOIN tt bb ON aa.id = bb.id
    WHERE [aa.somecondition]
    GROUP BY aa.id
)
SELECT a.id, a.price
FROM
    basequery as a
WHERE
    a.price >= ALL (SELECT price FROM basequery)
查看更多
登录 后发表回答