【问题标题】:How to properly pull out records constrained by a date calculation from a joined table in MySQL?如何从 MySQL 中的连接表中正确提取受日期计算约束的记录?
【发布时间】:2012-08-01 07:37:43
【问题描述】:

我从以下查询中得到以下结果:

SELECT users.ID, user_registered, post_date, post_type
FROM users LEFT OUTER JOIN posts ON users.ID = post_author
ORDER BY ID, user_registered, post_date, post_type

  ID   user_registered          post_date      post_type
---+-----------------+------------------+--------------+
   1    6/18/2012 4:04     6/18/2012 4:04           page
   1    6/18/2012 4:04     6/18/2012 4:04           post
   1    6/18/2012 4:04    6/18/2012 10:32  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:32  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:32  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:32  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:32  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:33  nav_menu_item
   1    6/18/2012 4:04    6/18/2012 10:48     attachment
   1    6/18/2012 4:04    6/19/2012 10:32     attachment
   1    6/18/2012 4:04     6/30/2012 6:49  nav_menu_item
   1    6/18/2012 4:04     6/30/2012 7:04  nav_menu_item
   1    6/18/2012 4:04      7/1/2012 7:39     attachment
   1    6/18/2012 4:04    7/13/2012 10:00           page
   1    6/18/2012 4:04    7/20/2012 18:18           page
   1    6/18/2012 4:04    7/21/2012 16:37           post
   1    6/18/2012 4:04    7/23/2012 14:15           page
   1    6/18/2012 4:04    7/31/2012 15:12           post
   1    6/18/2012 4:04      8/1/2012 8:47     attachment
   2   6/19/2012 10:05              NULL            NULL
   6    6/29/2012 4:47    6/19/2012 10:11     attachment
   6    6/29/2012 4:47    6/19/2012 10:15     attachment
   6    6/29/2012 4:47    6/19/2012 10:17     attachment
   6    6/29/2012 4:47    6/19/2012 10:20     attachment
   6    6/29/2012 4:47    6/19/2012 10:22     attachment
   6    6/29/2012 4:47     6/28/2012 0:00       employee
   6    6/29/2012 4:47     6/29/2012 0:00       employee
   6    6/29/2012 4:47      8/1/2012 0:00       employee
   6    6/29/2012 4:47      8/2/2012 0:00       employee
   6    6/29/2012 4:47      8/2/2012 0:00       employee
   6    6/29/2012 4:47      8/2/2012 0:00       employee
   7    7/7/2012 16:52    7/31/2012 14:26           post
  20   7/21/2012 14:48    7/21/2012 21:53           post
  20   7/21/2012 14:48    7/22/2012 12:50           post
  21   7/27/2012 14:56              NULL            NULL
  • ID:用户 ID。唯一的主键
  • user_registered: 用户加入网站的日期时间
  • post_date: 用户创建帖子的日期时间
  • post_type:用户创建的帖子类型

    1. 我需要获取自用户上次发布employee 帖子以来的天数(post_date 其中post_type = 'employee')。
    2. 如果用户尚未发布employee 帖子,那么我需要获取自用户注册 (user_registered) 以来的天数。

要求

我只需要获取所有用户的ID

  1. 其最新的employee 发布日期是例如< 7days 或>= 14days,或BETWEEN 6 AND 14 根据需要;或
  2. 如果用户没有employee 帖子,则获取注册< 7days 或>= 14days 或BETWEEN 6 AND 14 的用户,如#1。

我针对< 7 案例尝试了以下查询:

SELECT users.ID
FROM users LEFT OUTER JOIN posts ON users.ID = post_author
GROUP BY ID
HAVING MIN(DATEDIFF(NOW(), IFNULL(post_date, user_registered))) < 7

它会按预期产生IDs 1、6 和 7,因为:

  1. 拥有employee 帖子的用户(6)没有其他post_types 的任何其他帖子;和
  2. 没有employee 帖子的用户 (1, 7) 从他们的user-registered 日期得到他们的计算。

但是当这个查询中断时

  1. 拥有employee 帖子的用户还拥有其他post_types

因为我无法将日期计算限制为仅限 employee post_type 的帖子。如果用户有postpageattachment,也就是说,比他最近的employee 晚2 天,则日期计算将返回postpage 的结果或attachment

所以我尝试包含WHERE post_type = 'employee',但只返回了ID 6,因为所有其他用户都没有employee 帖子。所以我失去了我的第二个要求。

我该怎么做?提前致谢。

【问题讨论】:

    标签: mysql datetime join where-clause having


    【解决方案1】:

    试试:

    您可以在聚合函数MIN 中使用CASE 表达式来推导post_dates 的最小日期差异,其中post_type 是“员工”。如果特定用户没有带有“员工”的post_types,请改用他/她的注册日期进行比较。

    SELECT    a.ID
    FROM      users a
    LEFT JOIN posts b ON a.ID = b.post_author
    GROUP BY  a.ID
    HAVING    IFNULL(
                  MIN(CASE b.post_type WHEN 'employee' THEN DATEDIFF(NOW(), b.post_date) END),
                  DATEDIFF(NOW(), MIN(a.user_registered))
              ) < 7
    

    【讨论】:

    • hm.. 这会返回一个空的结果集.. 在它上面工作直到我可以让它工作.. 还有其他想法吗?非常感谢
    • 感谢您的编辑。我知道我们快到了....会及时通知您。让我知道是否还有其他问题。非常感谢
    • @AnaBan,您的日期列的数据类型是什么数据类型?在您的示例结果中,这看起来不像是有效的 DATETIME 数据。
    • @AnaBan,好的,我将用 SQLFiddle 进行测试,我会回复你。
    • 顺便说一句,对于user_registered 场景,它也应该是DATEDIFF(对不起,如果问题中不清楚..)无论如何,我为用户6运行了另一个测试employee 帖子类型,HAVING 子句仍然从 user_registered 返回 DATEDIFF 而不是 post_date
    【解决方案2】:

    根据您的其他限制,这可能不是正确答案 - 如果您在员工注册时添加默认帖子怎么办?它会简化你的头痛吗?

    【讨论】:

    • 不幸的是,我无法控制数据库。可以从中提取记录。 ://
    • hmnn...正如预期的那样.....你能在问题或评论中完整地描述这两个表吗?
    【解决方案3】:

    我认为在 where 子句中添加 post_type = 'employee' 条件而不是在 join 子句中添加条件可以解决您的问题。

    SELECT users.ID
    FROM users 
         LEFT OUTER JOIN posts 
             ON users.ID = post_author AND 
                post_type = 'employee'
    GROUP BY ID
    HAVING MIN(DATEDIFF(NOW(), IFNULL(post_date, user_registered))) < 7
    

    【讨论】:

    • 嗯,这返回了一个空集。 :(
    • 再次检查您的数据。对于数据,请尝试将条件设为
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    相关资源
    最近更新 更多