sql >> Database >  >> RDS >> Mysql

Hiaten opvullen in data die zijn geretourneerd uit database - pure SQL-oplossing mogelijk?

Ja, het is beter om een ​​Numbers-tabel te maken (enkele kolom N) die niets anders bevat dan de getallen 0 tot 999. Het kan voor veel dingen worden gebruikt, niet in het minst een query zoals de onderstaande:

SELECT COUNT(t.click_date) as clicks,
    DATE_FORMAT(adddate($start_date, interval N day), '%d %M %Y') as point 
FROM Numbers
LEFT JOIN tracking t
    ON t.click_date >= adddate($start_date, interval N day)
    and t.click_date < adddate($start_date, interval (N+1) day)
WHERE N between 0 and datediff($start_date, $end_date)
GROUP BY N

Je gebruikt het verkeerde formaat. Het is HOOFDLETTERS W en niet lager voor dag van de week, dus '%W %M %Y' of '%d %M %Y' voor dag van de maand.http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format

U gebruikt GROUP BY DAY(FROM_UNIXTIME(click_date)) opmerking "dag" geen weekdag, maar je toont (of probeert) "%W" (weekdag) - kies er een, meng ze niet.

BEWERKEN: Als u liever geen Numbers-tabel wilt maken (maken als een echte tabel), kunt u er meteen een maken. Het zal niet mooi zijn.

Opmerking:N1, N2 en N3 hieronder combineren om een ​​mogelijk bereik van 0-999 te geven

SELECT COUNT(t.click_date) as clicks,
    DATE_FORMAT(adddate($start_date, interval N day), '%d %M %Y') as point 
FROM (
    select N1 * 100 + N2 * 10 + N3 as N
    from (
    select 0 N1 union all select 1 union all select 2 union all
    select 3 union all select 4 union all select 5 union all
    select 6 union all select 7 union all
    select 8 union all select 9) N1
    cross join (
    select 0 N2 union all select 1 union all select 2 union all
    select 3 union all select 4 union all select 5 union all
    select 6 union all select 7 union all
    select 8 union all select 9) N2
    cross join (
    select 0 N3 union all select 1 union all select 2 union all
    select 3 union all select 4 union all select 5 union all
    select 6 union all select 7 union all
    select 8 union all select 9) N3
    ) Numbers
LEFT JOIN tracking t
    ON t.click_date >= adddate($start_date, interval N day)
    and t.click_date < adddate($start_date, interval (N+1) day)
WHERE N between 0 and datediff($start_date, $end_date)
GROUP BY N

BEWERK #2: Een rechte datumtabel

Zet dit in een nieuw venster in phpMyAdmin of voer het uit als batch. Het creëert een tabel met de naam Datums, met elke afzonderlijke datum vanaf dag 1900-01-01 (of wijziging in het script) naar 2300-01-01 (of wijzigen).

DROP PROCEDURE IF EXISTS FillDateTable;

delimiter //
CREATE PROCEDURE FillDateTable()
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  drop table if exists datetable;
  create table datetable (thedate datetime primary key, isweekday smallint);

  SET @x := date('1900-01-01');
  REPEAT 
    insert into datetable (thedate, isweekday) SELECT @x, case when dayofweek(@x) in (1,7) then 0 else 1 end;
    SET @x := date_add(@x, interval 1 day);
    UNTIL @x > date('2300-01-01') END REPEAT;
END//
delimiter ;

CALL FillDateTable;

Met zo'n hulpprogrammatabel kan uw vraag slechts

. zijn
SELECT COUNT(t.click_date) as clicks,
    DATE_FORMAT(thedate, '%d %M %Y') as point 
FROM Dates
LEFT JOIN tracking t
    ON t.click_date >= thedate
    and t.click_date < adddate(thedate, interval 1 day)
WHERE thedate between $start_date and $end_date
GROUP BY thedate


  1. Hoe Extract() werkt in PostgreSQL

  2. Mysql:database naast gegevens dumpen

  3. SHA512-hash een wachtwoord in MySQL-database door Python

  4. Overeenkomsten en verschillen tussen RANK-, DENSE_RANK- en ROW_NUMBER-functies