【问题标题】:How to order/limit an inner join in MySQL?如何在 MySQL 中订购/限制内部连接?
【发布时间】:2017-12-01 21:48:43
【问题描述】:

我不擅长 SQL。我需要从我的数据库中获取某些信息。此信息是单个帐户下的用户 ID 及其用户名的列表。涉及 3 个表。

客户

  • customer_id

客户关系

  • relationship_type
  • child_id
  • parent_id

用户名

  • user_name -- 用户名的字符串值
  • customer_id -- 外键
  • start_stamp -- 时间戳
  • end_stamp -- 时间戳

我的 USER_NAME 数据库中有许多条目,因为可以更改用户名。 start_stamp 是 user_name 被激活的时候,end_stamp 是它结束的时候。通常,在打开的用户上,数据库中有一个 end_stamp 为空的条目(因为 user_name 当前处于活动状态)。但是,如果用户已关闭,则 USER_NAME.end_stamp 可能不为空,因为该用户名最近已停用。最初,我正在运行 end_stamp 为空的查询,但我没有在我的帐户下看到已关闭的用户。我想知道是否有办法从我的 user_name 表中返回最新的 user_name (并且只返回一个)。这是我的查询:

select distinct
    users.customer_id,
    accounts.customer_id,
    USER_NAME.user_name
from CUSTOMER users
    inner join CUSTOMER_RELATIONSHIP cr on cr.child_id = users.customer_id
        and cr.relationship_type = 1 -- Account/User relationship
    inner join CUSTOMER accounts on accounts.customer_id = cr.parent_id
        and accounts.customer_id = 25 -- given ID
    inner join USER_NAME on USER_NAME.customer_id = users.customer_id
        and USER_NAME.end_stamp is null

这不会返回已关闭用户的用户名。如果我删除“并且 USER_NAME.end_stamp 为空”,它将返回我不想要的数据(已过期的用户名)。但是,我确实希望能够查看已关闭用户最近关联的 user_name。

如何编写一个查询来排序 USER_NAME 内部连接并获取具有 1) 空 end_stamp 或 2) 最近 start_stamp 的条目?

【问题讨论】:

  • 我认为你根本不需要查询 end_stamp,而只需选择 start_stamp 的 MAX()。

标签: php mysql sql


【解决方案1】:

我会建议一个相关的子查询:

select c.*,
       (select un.user_name
        from user_name un
        where un.customer_id = c.customer_id
        order by (end_stamp is null) desc, end_stamp desc
        limit 1
       ) as most_recent_user_name
from customers c;

【讨论】:

  • 太棒了,真的太棒了。谢谢你。我想知道是否有办法根据 most_recent_user_name 过滤我的结果?
  • 我试图添加 WHERE most_recent_user_name LIKE '%six%' 但我得到错误代码:1054 Unknown column 'most_recent_user_name' in 'where clause'
  • @pyguy 。 . .在 MySQL 中,您可以使用 having 子句作为列别名的条件。
【解决方案2】:

听起来您想要每个用户的最新名称,无论他们是否已关闭。如果是这种情况,那么您可以这样做:

SELECT customer_id, acct_cust_id, user_name
FROM (
  select DISTINCT
      users.customer_id,
      accounts.customer_id AS acct_cust_id,
      USER_NAME.user_name,
      ROW_NUMBER() OVER(PARTITION BY users.customer_id ORDER BY USER_NAME.end_stamp DESC) AS MyRowNum
  from CUSTOMER users
      inner join CUSTOMER_RELATIONSHIP cr on cr.child_id = users.customer_id
          and cr.relationship_type = 1 -- Account/User relationship
      inner join CUSTOMER accounts on accounts.customer_id = cr.parent_id
          and accounts.customer_id = 25 -- given ID
      inner join USER_NAME on USER_NAME.customer_id = users.customer_id
    ) src
    WHERE MyRowNum = 1  
  • 删除了最后一个 INNER JOIN 中的 end_stamp IS NULL 子句
  • 添加了 ROW_NUMBER 以按 end_stamp 对每个 customer_id 的 UserName 值进行排名);不确定您使用的是什么数据库,但您可能需要在 ORDER BY 子句中添加更多逻辑,以确保具有 NULL customer_id 值的行排在最前面

您也可以删除其中的 DISTINCT。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多