【问题标题】:MySQL query for at least once in x daysMySQL 在 x 天内至少查询一次
【发布时间】:2015-02-19 15:19:49
【问题描述】:

我的桌子是这样的:

名称:用户交易数据
日期格式 DD/MM/YYYY 仅 4 个月的数据(9 月、10 月、11 月、12 月)

Id   User  Date
25   127   23/10/2014 
26   128   25/11/2014 
25   127   22/11/2014
47   17    22/1/2014
25   127   12/9/2014
25   127   22/12/2014 

如果我想查找其条目在 30 天内至少出现一次的用户。 答案应该是 127。因为用户 127 在所有 4 个月中至少出现一次
用户 128 在 11 月只完成了一笔交易。每个月至少没有完成一次交易,所以没有被选中

如何为此编写查询?

【问题讨论】:

  • Id 列是什么意思?显然,它不是主键。
  • ID 25 和 user127 的对应条目每个月都存在
  • 所以你想查询到今天为止每个月都有一个条目的所有用户ID?但是从哪个日期算起?
  • 请为您的表提供一个名称(这是人们在这里犯的一个非常常见的错误,尽管它仍然让我感到惊讶)。您还需要更清楚地解释您的目标。例如,如果有一个条目 (35, 27, 22/10/2014),是否有资格被选中? (35、27、21/10/2014)呢?需要哪些条目才能选择用户 27?
  • Mahesh,我认为你真的需要更仔细地考虑一下你真正想要做什么。

标签: mysql sql


【解决方案1】:

如果您知道要检查用户是否在场的日期,则可以选择所有行WHERE 日期在您的范围内。我会使用BETWEEN 关键字。例如,如果您想要在 3 月份活跃的用户,您可以执行以下操作:

SELECT *
FROM myTable
WHERE dateColumn BETWEEN '2014-03-01' AND '2014-03-31';

对于这个特定示例,您似乎希望用户在过去 4 个月的每个月中至少进行过一次购买。您可以做的是通过使用 DATE_SUB() 函数设置开始日期来获取过去 4 个月中每个月的行:

SELECT *
FROM myTable
WHERE date >= DATE_SUB(CURDATE(), INTERVAL 4 MONTH);

一旦你有了它,你可以添加一个GROUP BY 语句来按用户和月份分组,以获得每个用户和每个月的一行:

SELECT *
FROM myTable
WHERE date >= DATE_SUB(CURDATE(), INTERVAL 4 MONTH)
GROUP BY user, MONTH(date);

一旦你有了它,你就可以从中提取用户HAVING 四行,因为这意味着他们在四个月中的每一个月都进行了购买:

SELECT user
FROM(
  SELECT *
  FROM myTable
  WHERE date >= DATE_SUB(CURDATE(), INTERVAL 4 MONTH)
  GROUP BY user, MONTH(date)) t
GROUP BY user
HAVING COUNT(*) = 4;

这是SQL Fiddle 示例。

另外,这里有一些好的日期和时间functions 供您记住。

【讨论】:

    【解决方案2】:
    SELECT User, COUNT(*) AS number_of_presence FROM (
      SELECT DATE_FORMAT(`Date`,'%Y-%m') AS date_month, User    
      FROM `table`
    
      GROUP BY date_month, User 
    ) TMP 
    GROUP BY User
    HAVING number_of_presence = 4  
    

    group by 用于多次避免同一用户。

    SQL Fiddle

    【讨论】:

    • 不工作!你能解释一下约会需要做什么吗?
    【解决方案3】:

    我认为您在任意连续 30 天之后,对吗? 不幸的是,您可能必须将表连接到自身,因为它会查找 pairs 行。那么查询将是:

    select
      a1.User,
      a1.Date as fromDate,
      a2.Date as toDate,
      datediff(a1.Date, a2.Date) as span
    from appearances a1, appearances a2
    where
      a1.User=a2.User and
      a2.Date>a1.Date and
      datediff(a2.Date, a1.Date) <= 30;
    

    为记录创建结构:

    CREATE TABLE appearances
        (`Id` int, `User` int, `Date` date)
    ;
    
    INSERT INTO appearances
        (`Id`, `User`, `Date`)
    VALUES
        (25, 127, '2014-10-23'),
        (26, 128, '2014-11-25'),
        (25, 127, '2014-11-22'),
        (47, 17, '2014-01-22'),
        (25, 127, '2014-09-12'),
        (25, 127, '2014-12-22')
    ;
    

    小提琴:http://sqlfiddle.com/#!2/1a3363/7/0

    【讨论】:

      【解决方案4】:
      SELECT * 
      FROM TABLE_NAME
      WHERE Date_Column >= DATEADD(MONTH, -1, GETDATE()) 
      

      SELECT * 
      FROM TABLE_NAME
      WHERE Date_Column >= DATEADD(DAY, -30, GETDATE())
      

      https://stackoverflow.com/a/21912827

      【讨论】:

        猜你喜欢
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 2011-10-21
        相关资源
        最近更新 更多