SQL query that returns all dates not used in a table

后端 未结 4 1017
一个人的身影
一个人的身影 2020-12-18 10:44

So lets say I have some records that look like:

2011-01-01 Cat
2011-01-02 Dog
2011-01-04 Horse
2011-01-06 Lion

How can I construct a query

相关标签:
4条回答
  • 2020-12-18 10:51

    The way to extract rows from the mysql database is via SELECT. Thus you cannot select rows that do not exist.

    What I would do is fill my blog table with all possible dates (for a year, then repeat the process)

     create table blog (
        thedate date not null,
        thetext text null,
        primary key (thedate));
    

    doing a loop to create all dates entries for 2011 (using a program, eg $mydate is the date you want to insert)

      insert IGNORE into blog (thedate,thetext) values ($mydate, null);
    

    (the IGNORE keyword to not create an error (thedate is a primary key) if thedate exists already).
    Then you insert the values normally

      insert into blog (thedate,thetext) values ($mydate, "newtext") 
      on duplicate key update thetext="newtext";
    

    Finally to select empty entries, you just have to

      select thedate from blog where thetext is null;
    
    0 讨论(0)
  • 2020-12-18 10:54

    You probably not going to like this:

    select '2011-01-03', count(*) from TABLE where postdate='2011-01-03' 
      having count(*)=0 union
    select '2011-01-04', count(*) from TABLE where postdate='2011-01-04' 
      having count(*)=0 union
    select '2011-01-05', count(*) from TABLE where postdate='2011-01-05' 
      having count(*)=0 union
    ... repeat for 2 weeks
    

    OR

    create a table with all days in 2011, then do a left join, like

    select a.days_2011
    from all_days_2011
    left join TABLE on a.days_2011=TABLE.postdate
    where a.days_2011 between date(now()) and date(date_add(now(), interval 2 week))
    and TABLE.postdate is null;
    
    0 讨论(0)
  • 2020-12-18 10:57

    You're right — SQL does not make it easy to identify missing data. The usual technique is to join your sequence (with gaps) against a complete sequence, and select those elements in the latter sequence without a corresponding partner in your data.

    So, @BenHoffstein's suggestion to maintain a permanent date table is a good one.

    Short of that, you can dynamically create that date range with an integers table. Assuming the integers table has a column i with numbers at least 0 – 13, and that your table has its date column named datestamp:

       SELECT candidate_date AS missing
         FROM (SELECT CURRENT_DATE + INTERVAL i DAY AS candidate_date
                 FROM integers
                WHERE i < 14) AS next_two_weeks
    LEFT JOIN my_table ON candidate_date = datestamp
        WHERE datestamp is NULL;
    
    0 讨论(0)
  • 2020-12-18 11:14

    One solution would be to create a separate table with one column to hold all dates from now until eternity (or whenever you expect to stop blogging). For example:

    CREATE TABLE Dates (dt DATE);
    INSERT INTO Dates VALUES ('2011-01-01');
    INSERT INTO Dates VALUES ('2011-01-02');
    ...etc...
    INSERT INTO Dates VALUES ('2099-12-31');
    

    Once this reference table is set up, you can simply outer join to determine the unused dates like so:

    SELECT d.dt 
    FROM Dates d LEFT JOIN Blogs b ON d.dt = b.dt 
    WHERE b.dt IS NULL
    

    If you want to limit the search to two weeks in the future, you could add this to the WHERE clause:

    AND d.dt BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 14 DAY)
    
    0 讨论(0)
提交回复
热议问题