Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Uzupełnianie braków w datach zwróconych z bazy danych - czy możliwe jest rozwiązanie czysto SQL?

Tak, lepiej jest utworzyć tabelę liczb (pojedyncza kolumna N), która zawiera tylko liczby od 0 do 999. Może być używana do wielu rzeczy, nie tylko do zapytania takiego jak poniżej:

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

Używasz złego formatu. WIELKIE litery W nie są mniejsze dla dnia tygodnia, więc '%W %M %Y' lub '%d %M %Y' na dzień miesiąca.http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format

Używasz GROUP BY DAY(FROM_UNIXTIME(click_date)) uwaga "dzień" nie w dzień powszedni, ale wyświetlasz (lub próbujesz) "%W" (dzień powszedni) - wybierz jeden, nie mieszaj ich.

EDYTUJ: Jeśli wolisz nie materializować (tworzyć jako rzeczywistej tabeli) tabeli sekwencji liczb, możesz utworzyć ją w locie. Nie będzie ładnie.

Uwaga:N1, N2 i N3 poniżej łączą się, dając możliwy zakres 0-999

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

EDYCJA #2: Prosta tabela dat

Umieść to w nowym oknie w phpMyAdmin lub uruchom jako wsad. Tworzy tabelę o nazwie Dates, z każdą pojedynczą datą od dnia 1900-01-01 (lub zmień w skrypcie) na 2300-01-01 (lub zmień).

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;

Przy takiej tabeli narzędziowej zapytanie może być po prostu

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak ustawić maksymalną liczbę wierszy w tabeli MySQL?

  2. Czy istnieje prostszy sposób na osiągnięcie tego stylu komunikacji z użytkownikami?

  3. Nie mogę zainstalować mysql-python (nowsze wersje) w systemie Windows

  4. Ostrzeżenie:mysql_fetch_array() oczekuje, że parametr 1 będzie zasobem [...]

  5. Mysql usuwa określone słowo w ciągu oddzielonym przecinkami