Question

I need to select one row with the "highest" date and time from a table, but I can't get the highest one, the ORDER BY DESC doesn't work. Here's my query:

SELECT count(*) as c, 
       start, 
       UNIX_TIMESTAMP(start) as S, 
       duration
  FROM appuntamento
 WHERE DATE(start) = DATE('2014-04-08 18:30:00') 
 ORDER BY S DESC 
 LIMIT 1

I don't care about getting the start value in unix timestamp, it was the nth try to get through this

Any tips?

Was it helpful?

Solution

A few problems here. First, the presence of COUNT(*) turns this into an aggregate query, which do you not want. That's probably the cause of your trouble.

Second, if you have a lot of rows in your appuntamento table the performance of this query will be bad, because you can't use an index.

Presuming that you want the time and duration of the last (latest-in-time) row from a particular day in your table, and the number of appointments for that same day, you need to do this:

 SELECT a.start, a.duration, b.count
   FROM (
         SELECT start,
                duration
           FROM appuntamento
          WHERE start >= DATE('2014-04-08 18:30:00')
            AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
          ORDER BY start DESC, duration DESC
          LIMIT 1
        ) AS a
    JOIN (
         SELECT COUNT(*) AS count
           FROM appuntamento
          WHERE start >= DATE('2014-04-08 18:30:00')
            AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY
         ) AS b

Explanation: First, this form of searching on start allows you to use an index on the start column. You want that for performance reasons.

          WHERE start >= DATE('2014-04-08 18:30:00')
            AND start < DATE('2014-04-08 18:30:00') + INTERVAL 1 DAY

Second, you need to handle the COUNT(*) as a separate subquery. I have done that.

Third, you can definitely do ORDER BY start DESC and it will work if start is a DATETIME column. No need for UNIX_TIMESTAMP().

Fourth, I used ORDER BY start DESC, duration DESC to arrange to return the longest appointment if there happen to be several with the same start time.

OTHER TIPS

if all you want is one row returned then use the MAX() function without the order. should do the trick.

SELECT count(*) as c, 
       MAX(start) as highest_date, 
       UNIX_TIMESTAMP(start) as S, 
       duration
  FROM appuntamento
 WHERE DATE(start) = DATE('2014-04-08 18:30:00') 

also with your order by statement. you need to add a group by so that you aren't combining incorrect rows with the COUNT() aggregate.

 SELECT count(*) as c, 
       start, 
       UNIX_TIMESTAMP(start) as S, 
       duration
 FROM appuntamento
 WHERE DATE(start) = DATE('2014-04-08 18:30:00') 
 GROUP BY S
 ORDER BY S DESC 
 LIMIT 1
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top