简体   繁体   中英

Obtaining a max row using EXISTS with additional condition/s

I have a table in MySQL database namely weight . It can be viewed in the following snap shot.

The weight table:

重量 :

I need the following query.

SELECT * 
FROM   weight w 
WHERE  w.weight_id IN (SELECT MAX(ww.weight_id) 
                       FROM   weight ww 
                       WHERE  ww.weight BETWEEN 0 AND 60);

Linguistically obtaining a max row from the weight table from among the rows where the weight column has a value between 0 and 60 (for example).


I want the same query using EXISTS() . The following attempt is unsuccessful.

SELECT * 
FROM   weight w 
WHERE  NOT EXISTS (SELECT 1 
               FROM   weight ww 
               WHERE  w.weight_id < ww.weight_id 
                      AND ww.weight BETWEEN 0 AND 60);

It returns all rows starting from the max row (if the BETWEEN condition ( AND ww.weight BETWEEN 0 AND 60 ) is omitted then, it returns a max from all the rows in the table but it is undesired. It should return a max row after applying a filter according to the BETWEEN condition).

A slightly modified version returns no rows.

SELECT * 
FROM   weight w 
WHERE  EXISTS (SELECT 1 
               FROM   weight ww 
               WHERE  w.weight_id = ww.weight_id 
                      AND ww.weight BETWEEN 0 AND 60 
                      AND NOT EXISTS(SELECT 1 
                                     FROM   weight www 
                                     WHERE  ww.weight_id < www.weight_id)) 

Can I still have an alternative to use EXISTS() ?

I'm using an ORM framework where a subquery is not supported in the FROM clause. Therefore, it would be far better, if a subquery in the FROM is excluded.

Generally speaking id should only be used as a row identifier and not compared using MAX() .

If you want one row with the greatest weight between two values:

  SELECT id, weight
    FROM weight
   WHERE weight BETWEEN 0 AND 60
ORDER BY weight DESC
   LIMIT 1

I would not use EXISTS in this instance.

UPDATE

If you cannot use LIMIT then:

  SELECT id, weight
    FROM weight
   WHERE weight = (
    SELECT MAX(wi.weight)
      FROM weight wi 
     WHERE wi.weight BETWEEN 0 AND 60
         )

will return the same providing there is no dupe on MAX(weight)

If you insist on using EXISTS then you could try:

 SELECT * 
   FROM weight w 
  WHERE NOT EXISTS (
   SELECT 1 
     FROM weight ww 
    WHERE w.weight < ww.weight 
      AND ww.weight BETWEEN 0 AND 60
        )
    AND w.weight BETWEEN 0 AND 60

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM