【问题标题】:mysql LEFT JOIN select query with limited resultsmysql LEFT JOIN 选择查询,结果有限
【发布时间】:2025-11-26 16:40:01
【问题描述】:

我正面临一种情况,需要帮助。我有两张桌子:

用户:

  • user_idfnamelnameemail

user_timesheet:

  • time_iduser_idmonthstatedate

用户将向user_time 表添加时间,状态为 = 'no',并在月底提交更改状态 = 'yes' 的时间,假设月份为 JUNE 我想写一个查询,它将把所有没有添加时间的用户和添加了时间但还没有提交六月的用户。

这是我的查询。

SELECT user_timesheet.time_id, user_timesheet.user_id, 
    user_timesheet.month, user_timesheet.`state`, 
    `user`.user_id, `user`.fname, `user`.lname,  
    `user`.email
FROM user LEFT JOIN  
     user_timesheet ON user.user_id=user_timesheet.user_id
WHERE (
    user_timesheet.state = 'no' OR 
    user_timesheet.state IS NULL) 
AND (
    user_timesheet.month = 'june' OR 
    user_timesheet.month IS NULL)
GROUP BY user.user_id

结果会将所有在 6 月添加时间但已提交的用户以及自加入后从未添加时间的用户带到系统。但是,它不会带来上个月添加时间或提交时间但根本没有添加 6 月份时间的用户。

【问题讨论】:

    标签: mysql sql join where


    【解决方案1】:

    在 where 子句中将过滤器放在 ON 子句中,而不是 (a = x or a is null)。这将删除不匹配的记录,但保留左连接的性质。

    要将“否”状态视为不存在的行,将其从左连接中过滤掉:

    SELECT user_timesheet.time_id, user_timesheet.user_id, 
           user_timesheet.month, user_timesheet.`state`, 
           `user`.user_id, `user`.fname, `user`.lname,  
           `user`.email
      FROM user 
      LEFT JOIN user_timesheet
      -- Eliminate users who have submitted 'no'
      -- For June
        ON user.user_id=user_timesheet.user_id
        -- Turn 'no' status into null record
       AND user_timesheet.state <> 'no'
       AND user_timesheet.month = 'june'
      -- If there is no row in user_timesheet
      -- It means that
      --    a) There was not any
      --    b) There was a 'no' status
     WHERE user_timesheet.user_id is null
     GROUP BY user.user_id
    

    注意:我不知道 MySql 中的注释标记是什么。它是 -- 在 Sql Server 中,所以在尝试查询之前删除此行。

    【讨论】:

    • 非常感谢。请问一下,这个在声明中是什么意思
    • @user1451414 表示标准 sql 中的 not equal。欢迎你:-)
    • @user1451414 在功能上,没有。但是,当在相同值的专有语法和标准语法之间进行选择时,我选择标准。当您必须切换 DB 时,生活会轻松一点。
    【解决方案2】:
    SELECT user_timesheet.time_id, user_timesheet.user_id, user_timesheet.month, user_timesheet.`state`, 
           `user`.user_id, `user`.fname, `user`.lname, `user`.email
      FROM user 
      LEFT JOIN user_timesheet
        ON user.user_id=user_timesheet.user_id
        AND user_timesheet.month = 'june' AND user_timesheet.state = 'no'
    

    【讨论】:

    【解决方案3】:

    首先创建一个查询,该查询与在指定时间段内添加时间且状态为“YES”的所有用户的 userId 匹配 => 您拥有所有“好”用户。那么您必须选择不在该列表中的所有用户。您可以在子查询或减号查询中使用不存在、不存在。

    不在的例子:

    SELECT user_timesheet.time_id, user_timesheet.user_id, user_timesheet.month, user_timesheet.`state`, `user`.user_id, `user`.fname, `user`.lname,  `user`.email
      FROM user LEFT JOIN user_timesheet ON user.user_id=user_timesheet.user_id
    where user.user_id not in (
      select user.user_id 
        from user inner join user_timesheet ON user.user_id=user_timesheet.user_id 
      where user_timesheet.state = 'yes' 
      AND user_timesheet.month = june
      )
    )
    

    【讨论】: