3

I have a problem with a SQL select query, I can't figure out what it needs to be.

This is what my items table look like:

| id |   i_id   |      last_seen       |   spot    |
----------------------------------------------------
| 1  |   ls100  | 2017-03-10 15:30:40  |  spot800  |
| 2  |   ls100  | 2017-03-10 16:20:15  |  spot753  |
| 3  |   ls200  | 2017-03-10 16:33:10  |  spot800  |
| 4  |   ls300  | 2017-03-10 15:30:40  |  spot800  |
| 5  |   ls300  | 2017-03-10 12:10:30  |  spot800  |
| 6  |   ls400  | 2017-03-10 10:30:10  |  spot800  |

This is what I'm trying to obtain:

 | id |   i_id   |      last_seen       |   spot    |
 ----------------------------------------------------
 | 3  |   ls200  | 2017-03-10 16:33:10  |  spot800  |
 | 5  |   ls300  | 2017-03-10 12:10:30  |  spot800  |

So I need to have the rows where spot= 'spot800', last_seen = MAX(but only if the DateTime is the newest compared to all spots with the samei_id`), and at last the DateTime must be bigger than '2017-03-10 11:00:00'.

This is what I have so far:

SELECT * 
  FROM items
 WHERE spot = 'spot800' 
HAVING MAX(`last_seen`) 
   AND `last_seen` > '2017-03-10 11:00:00' 
2
  • whether your query returning any records? Commented Mar 10, 2017 at 10:24
  • 1
    You forgot grouping by i_id Commented Mar 10, 2017 at 10:25

3 Answers 3

2

E.g.:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,i_id   INT NOT NULL
,last_seen       DATETIME NOT NULL
,spot    INT NOT NULL
);

INSERT INTO my_table VALUES
(1,100,'2017-03-10 15:30:40',800),
(2,100,'2017-03-10 14:20:15',753),
(3,200,'2017-03-10 16:33:10',800),
(4,300,'2017-03-10 15:30:40',800),
(5,300,'2017-03-10 12:10:30',800),
(6,400,'2017-03-10 10:30:10',800);

    SELECT [DISTINCT] x.* 
      FROM my_table x
      LEFT
      JOIN my_table y
        ON y.i_id = x.i_id
       AND y.last_seen < x.last_seen
     WHERE x.last_seen > '2017-03-10 11:00:00' 
       AND x.spot = 800
       AND y.id IS NULL;
----+------+---------------------+------+
| id | i_id | last_seen           | spot |
+----+------+---------------------+------+
|  3 |  200 | 2017-03-10 16:33:10 |  800 |
|  5 |  300 | 2017-03-10 12:10:30 |  800 |
+----+------+---------------------+------+
2 rows in set (0.00 sec)
Sign up to request clarification or add additional context in comments.

9 Comments

I still get id 1 returned and this one shouldn't be returned because its date is older than that from id 2
Also the date in row 2 should be '2017-03-10 16:20:15'
@SerAkd You're welcome. You wanted rows with ids 3 & 5. It makes no sense (to me) to return a time and id that don't correspond.
Indeed I wanted those rows, but when I execute the query it also returns id 1?
Plainly, that's not true. See above.
|
0

Use MAX and GROUP BY.

SELECT id, i_id, MAX(last_seen), spot  
FROM items
WHERE spot = 'spot800'
AND last_seen > '2017-03-10 11:00:00'
GROUP BY id, i_id, spot

3 Comments

because that matches your logic, id 1 is returned because it is the MAX last_seen for the ls100s
My apologies, I forgot to edit it, id 1 shouldn't be the MAX last_seen
If i use : GROUP BY i_id instead of GROUP BY id, i_id, spot then it returns the rows with id 1,3 and 5
0

There is several things wrng with your statement.

Firstly, HAVING must be accompanied with a GROUP BY clause, so it's not what you are looking for.

Also, MAX is an aggregate, not a boolean, function. That is, it cannot be used in filters, such as a where clause or a having clause. Also, if it did work, MAX would only return the entry that contains the time as '2017-03-10 16:33:10'. Not what you expected.

Try this instead:

SELECT * FROM items WHERE (spot='spot800' AND last_seen > '2017-03-10 11:00:00');

2 Comments

HAVING doesn't have to follow a GROUP BY clause - although that is its primary purpose. And your solution is incomplete, but otherwise, good.
This query returns the rows with id 1,3,4,5 and it only needs to return the rows with id 3 and 5

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.