1

有必要为某些日期选择值,我知道该怎么做,但是有一个问题无法解决。

我在 MySQL 中的表:

[User]. [Wins]. [DATE]
#
Ivan ....... 4 ..... 05/06/2010
#
Ivan ....... 3 ..... 06/15/2010
#
Ivan ........ 6 ..... 06/18/2010
#
Ivan ........ 1 ..... 29/06/2010

问题是,如果用户没有访问过该站点,则不会在数据库中创建一行并且错过了获得的日期。

如何获得统计数据(例如 Wins 0),例如从 06/06/2010 到 06/14/2010 的期间?帮助进行此查询。

4

3 回答 3

3

MySQL 没有递归功能,因此您只能使用 NUMBERS 表技巧 -

  1. 创建一个只包含递增数字的表 - 使用 auto_increment 很容易做到:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. 使用以下方法填充表:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...根据需要获取尽可能多的值。

  3. 使用DATE_ADD构造日期列表,根据 NUMBERS.id 值增加天数:

    SELECT x.*
      FROM (SELECT DATE_FORMAT(DATE_ADD('2010-06-06', INTERVAL n.id - 1 DAY), '%m/%d/%Y') 
              FROM numbers n
             WHERE DATE_ADD('2010-06-06', INTERVAL n.id -1 DAY) <= '2010-06-14 ) x
    
  4. 根据时间部分向您的数据表 LEFT JOIN:

       SELECT x.ts AS timestamp,
              COALESCE(COUNT(y.wins), 0) AS cnt
         FROM (SELECT DATE_FORMAT(DATE_ADD('2010-06-06', INTERVAL n.id - 1 DAY), '%m/%d/%Y') AS ts
                 FROM numbers n
                WHERE DATE_ADD('2010-06-06', INTERVAL n.id - 1 DAY) <= '2010-06-14') x
    LEFT JOIN TABLE y ON STR_TO_DATE(y.date, '%m/%d/%Y') = x.ts
     GROUP BY x.ts
    
于 2010-08-03T03:48:19.550 回答
0

在“wins”字段上尝试“sum”聚合函数并将其(使用 where)限制在特定的日期范围内(因此 date<='6/14/2010' AND date>='06/06/2010')。

所以像 SELECT SUM(wins) FROM [tbl_name] WHERE [DATE] between [date1] AND [date2]

获取每个日期范围内的获胜次数;添加“按 [user] 分组”,以查看每个用户在该日期范围内的获胜次数。

于 2010-08-03T03:15:00.240 回答
0

这是我怀疑可以解决问题的答案。我创建了一个临时表来为您提供日期列表(我使用带有开始和结束日期的循环插入。计数器必须从 0 开始,因为您想包含开始日期本身)。

然后,我只是将 DateList 加入 Wins 表,为您提供该范围内所有日期的列表、用户及其在这些日期的访问。我尚未对其进行测试,但我怀疑代码接近于您所需要的。

DECLARE Counter INT DEFAULT 0
DECLARE NumDays INT DEFAULT DATEDIFF(StartDate, EndDate)

CREATE TEMPORARY TABLE DateList
(
    [Date] DATETIME
)

WHILE Counter <= NumDays
    INSERT INTO DateList ([Date]) VALUES (DATE_ADD(StartDate, INTERVAL Counter Day))
    SET Counter = Counter + 1
END WHILE

SELECT
    [User]  
    ,COUNT(User) AS Wins
    ,DateList.[Date] AS [Date]
FROM
    DateList LEFT JOIN Wins ON Wins.[Date] = DateList.[Date]
WHERE
    DateList.[Date] BETWEEN StartDate AND EndDate
GROUP BY
    [User]
    ,DateList.[Date]
ORDER BY
    DateList.[Date]

编辑:我对我的加入和计数进行了一些更改。我已经测试了 MSSQL 版本,它工作正常。

于 2010-08-03T03:23:45.107 回答