如何在MySQL中订购/限制内部联接?

时间:2017-12-01 21:48:44

标签: php mysql sql

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

CUSTOMER

  • CUSTOMER_ID

CUSTOMER_RELATIONSHIP

  • relationship_type
  • child_id
  • PARENT_ID

USER_NAME

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

我的USER_NAME数据库中包含许多条目,因为可以更改用户名。 start_stamp是在激活user_name时,end_stamp是在它结束时。通常,在打开的用户上,数据库中有一个条目,其中end_stamp为null(因为user_name当前处于活动状态)。但是,如果用户已关闭,则USER_NAME.end_stamp可能不为null,因为用户名最近已停用。最初我正在运行一个查询,其中end_stamp为null,但我没有看到我帐户下的已关闭用户。我想知道是否有办法从我的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为null"它将返回我不想要的数据(用户名已过期)。但是,我希望能够为已关闭的用户查看最近关联的user_name。

如何编写一个查询,用于订购USER_NAME内部联接并获取带有1)null end_stamp或2)最新start_stamp的条目?

2 个答案:

答案 0 :(得分:3)

我建议使用相关的子查询:

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;

答案 1 :(得分:0)

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

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。