Trouble comparing dates in two tables

I found a bug in my website where the user’s most recent login was not being recorded. I discovered this by seeing more recent dates in the searches table compared to what I’m seeing in the users table. The problem I ran into is that the date column in the searches table uses the date and time. The date column in the users table is setup to only show the date. So in the query below I formatted the date in the search column to look like the date column in the users table. Unfortunately, the database still sees the dates in the search column to be greater, simply because there is also a time as part of the date. Can someone help me tweak my query so I can really find the users that have a more recent date in the searches table compared to the users table?

Thanks!


-- Accounts where the date in search table is more recent than the users table.
SELECT
   u.date,
   u.uID,
   u.firstname,
   u.visited,
   u.last as lastLogin,
   date_format(s.date, '%Y-%m-%d') as searchDate
 FROM users u
INNER
 JOIN searches s
   ON u.uID = s.author
WHERE
  s.date > u.last
GROUP BY
 u.uID
ORDER BY u.last
  limit 100;


remove the GROUP BY clause

Thanks Rudy, I took out that line and the query runs fine. But I’m still stumped on how to resolve the fact that the searches table is using full dates, including the time, and the users table is just storing dates as 2011-05-12. Because of this difference, the query is showing a lot of rows where it thinks the date in the searches table is more recent, I’m guessing because the time is included. Should I do an update on the users table and convert all of the last login dates to use the kind of date with time? Or is there a better way to get around this?

Once I can get this worked out, then I plan on using the following query to fix this mess. Does this look good to you?


UPDATE users u, searches s
SET u.last = s.date
WHERE s.date=(select date from searches where author =u.uID order by date desc limit 1) AND
s.date > u.last AND
u.uID = s.author

i don’t think you’ve explained the problem adequately enough for me to offer an opinion

for starters, why are there two date/datetime columns?

One date column is used in the users table. This records the last login date. The other datetime column is in the searches table. It records when a search was conducted by the website user.

okay, those are good reasons for separate columns

and you’re saying that they’re out of sync?

have you fixed the source of the problem yet?

Yes, they are out of sync. I found a bug in my website code where the last login date was not being updated in the users table. No telling how long that bug has been there. I have since fixed in and now it updates when people login. So the goal is to find their most recent visit date based on the searches they have conducted. Then copy the date of the search over into the users table.

Thanks!!

okay, i’ll walk you through it, we’re going to do this in two steps

the first step is to write a query which gets the most recent search date for each user

Ok, here is the one I’ve been working on today that will do that very thing:

-- Accounts where the date in search table is more recent than the users table.
SELECT
  u.uID,
  u.date as registerDate,
  u.firstname,
  u.last as usersVisit,
  date_format(s.date, '%Y-%m-%d') as searchesVisit
FROM users u
INNER
JOIN searches s
  ON u.uID = s.author
WHERE
 s.date=(select date from searches where author =u.uID order by date desc limit 1) AND
 s.date > u.last
ORDER BY u.uID
 limit 100;

no, that’s not what i was after, i wanted just the most recent search date for each userid, it’s just a simple one-table query using the searches table

combining it with the users table was step 2

Ok, here you go:

select author, date from searches group by author order by author;

that’s almost right, but you’re missing the MAX function (and ORDER BY doesn’t matter here)

SELECT author
     , MAX(date) AS latest
  FROM searches
GROUP
    BY author

the next step is to join this subquery to the users table

ever done that? join a subquery to a table?

Here is what I came up with. Remember, however, that s.date is a datetime and u.last is just a date. So I’m wondering how we will proceed next to accurately campare the two. Also, why is MAX used in this case when grouping it by author should only return one row per user.

SELECT s.author
, u.firstname
, u.last
, MAX(s.date) AS searchDate
FROM users u
INNER JOIN
searches s
on u.uID = s.author
GROUP
BY author;

MAX is used because you want the latest value of the datetime, i.e. the largest value

if you do this –

SELECT author, date FROM searches GROUP BY author

then the value of the date column that is returned for each author is indeterminate – it could be any of the values for each author

since you want the latest one, you must do this –

SELECT author, MAX(date)  FROM searches GROUP BY author

see the difference?

as for step 2, i don’t think you understood what i was saying about joining to the subquery…

SELECT ...
  FROM users u
INNER 
  JOIN ( SELECT author
              , MAX(date) AS latest
           FROM searches 
         GROUP 
             BY author ) AS s
    ON s.author = u.uID

see how the subquery is used, in the FROM clause a subquery is called a derived table

play with that for a minute, and convince yourself it’s working correctly, then we’ll proceed to the update

Rudy, how come when I run the following query I get an error that says, “Unknown column s.date in field list”? I wanted to not only show the date of their last login (u.last) but also the date of the most recent search (s.date)

SELECT u.uID
, u.last
, s.date
FROM users u
INNER
JOIN (SELECT author, MAX(date) AS latest FROM searches GROUP BY author ) AS s
ON s.author = u.uID;

in this query, the table alias “s” refers to the subquery, not to the searches table

the subquery has only two columns, author and latest

that’s why you got the error message

:slight_smile:

Ok, I got the query fixed by changing latest to date.

SELECT u.uID
, u.last
, s.date
FROM users u
INNER
JOIN (SELECT author, MAX(date) AS date FROM searches GROUP BY author ) AS s
ON s.author = u.uID
WHERE
s.date > u.last;

I also added a check in the WHERE clause. The problem is that the s.date is a datetime and u.last is just a date. So the query is returning incorrect results thinking that dates are greater when they really aren’t. As you can see from the top of this thread, I tried to convert the datetime to just a date using “date_format(s.date, ‘%Y-%m-%d’) as searchDate” but that didn’t work.

Before we can move on to the update, I gotta figure out what I’m doing wrong with the date compare.

Thanks!

you shoulda changed it the other way around – it’s still the same query, but the intent of what you’re doing is clearer

SELECT u.uID
     , u.last
     , s.[COLOR="Blue"]latest[/COLOR]
  FROM users u
INNER 
  JOIN ( SELECT author
              , [COLOR="blue"]MAX(date) AS latest[/COLOR]
           FROM searches 
         GROUP 
             BY author ) AS s
    ON s.author = u.uID
 WHERE s.[COLOR="blue"]latest [/COLOR]> u.last

that’s not a problem, and you don’t need to do any conversion

please show a few rows of results which you think are wrong

The first row:

uID = 121
last = 2011-03-10
latest = 2011-03-10 06:56:26

So the query thinks that somehow 2011-03-10 06:56:26 is greater than just 2011-03-10. Make sense?

of course it does :slight_smile:

2011-03-10 is the same as 2011-03-10 00:00:00 (midnight on the morning of the day)

and 2011-03-10 06:56:26 ~is~ greater than 2011-03-10 00:00:00 (almost 7 hours past midnight)