简体   繁体   中英

INSERT only if SELECT returns no rows

I'm tracking a users visit to a website by recording them in a database. A visit has a cooldown period of 6 hours. For this reason, I want to add a row to the table visits only if a user last visited the current website over 6 hours ago. If the last visit was less than 6 hours ago, do nothing.

I've looked around for answers to this and found plenty of quite similar issues, but none of those worked for me.

This is last query I tried:

INSERT INTO visits (user_id, web_id)
   SELECT (66, 2) FROM websites WHERE NOT EXISTS (
     SELECT 1 FROM visits WHERE web_id = 2 and user_id = 66 and added_on >= NOW() - INTERVAL 6 HOUR
   )

I'm getting a syntax error near WHERE NOT EXISTS .

You might want to enforce this rule with a trigger rather than in the application. But I think the problem are the parentheses in the SELECT clause:

INSERT INTO visits (user_id, web_id)
    SELECT 66, 2 
    FROM websites
    WHERE NOT EXISTS (SELECT 1
                      FROM visits
                      WHERE web_id = 2 and user_id = 66 and
                            added_on >= NOW() - INTERVAL 6 HOUR
                     );

Hmmm . . . Your query is strange. What is websites ? Your query is going to insert one row for every row in that table. It seems unlikely that you want this behavior. Perhaps you just want this:

INSERT INTO visits (user_id, web_id)
    SELECT w.user_id, w.web_id
    FROM (SELECT 66 as user_id, 2 as web_id) w
    WHERE NOT EXISTS (SELECT 1
                      FROM visits v
                      WHERE v.web_id = w.web_id and
                            v.user_id = w.user_id and
                            v.added_on >= NOW() - INTERVAL 6 HOUR
                     );

you might try this ...

INSERT visits (user_id, web_id)
SELECT distinct user_id, web_id 
FROM websites t join websites b 
   on b.user_id = t.user_id
       and b.web_id  = t.web_id 
       and b.added_on = (Select Max(added_on) From websites
                         Where id = t.user_id
                            and web_id  = t.web_id
                            and added_on < t.added_on)  
WHERE t.added_on >= NOW() - INTERVAL 6 HOUR
  and user_id = 66 
  and web_id = 2

try the Select part by itself first, to see if it returns the correct result.

by the way, if you only have the userId and the webId in the visits table, without the datetime of the visit, how do you interpret the data when there are multiple rows for the same user/website combination, which are the result of visits more than six hours apart?

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