【问题标题】:Refining a double many-to-many JOIN提炼双多对多 JOIN
【发布时间】:2012-03-08 12:35:37
【问题描述】:

我有一个多对多的帐户 用户关系。我正在尝试提取我和另一个用户共享的所有帐户。到目前为止,我已经从this 修改了一些内容:

SELECT * 
    FROM user
    JOIN account_user ON account_user.user_id = user.id
    JOIN account ON account.id = account_user.account_id
   WHERE user.id IN ({my_id},{other_user_id})
GROUP BY account.id
  HAVING COUNT(DISTINCT user.id) = 2

这似乎在正确的轨道上,但account_user 表有一个“角色”字段,我想确保我返回的记录包含其他用户的角色,而不是我的。我将如何调整它以实现这一目标?

【问题讨论】:

  • 你能改一下这个问题吗?
  • 你的结果集中有2个角色字段的问题吗?如果是这样,您可以使用别名来让您的选择区分它们。

标签: sql many-to-many inner-join


【解决方案1】:

这适用于我的 Oracle,同样的基本思想应该适用于任何 DBMS:

SELECT account.*, role
FROM account
    JOIN account_user ON account_id = account.id AND user_id = :other_user_id
WHERE
    account.id IN (SELECT account_id FROM account_user WHERE user_id = :my_id)

简单的英语:

  • 为其他用户加入 accountaccount_user
  • 只接受那些连接到我的用户的帐户。

如果需要,您可以轻松加入 user(如您的 SQL 所示,但不是您的问题所示)。

【讨论】:

  • 布兰科-太棒了!非常干净,而且效果很好——很喜欢。 (我必须在我的系统中指定account.id 而不仅仅是id,因为出现了歧义错误......)
【解决方案2】:

在我的例子中,'user2' 是另一个用户,'user1' 是你:

-- query should work in most RDBMS
SELECT A1.account,
       AU1.role AS user_2_account_role,
       U1.uname AS user_2_name
FROM @account AS A1
JOIN @account_users AS AU1 ON AU1.account_id = A1.id
JOIN @user AS U1 ON U1.id = AU1.user_id
WHERE EXISTS(
    -- get accounts that are 'mine'
    SELECT *
    FROM @user AS U2
    JOIN @account_users AS AU2 ON AU2.user_id = U2.id
    WHERE U2.uname = 'user1' -- 'mine'
    AND AU2.account_id = AU1.account_id
)
AND U1.uname = 'user2' -- other user

我在 SQL Server 中准备的示例数据:

-- sample data in SQL SERVER
DECLARE @user TABLE(uname VARCHAR(20), id INT);
INSERT INTO @user(uname, id) 
VALUES('user1', 1),
      ('user2', 2),
      ('user3', 3),
      ('user4', 4);

DECLARE @account TABLE(account VARCHAR(20), id INT);
INSERT INTO @account(account, id)
VALUES('account1', 1),
      ('account2', 2),
      ('account3', 3),
      ('account4', 4);

DECLARE @account_users TABLE(account_id INT, user_id INT, role VARCHAR(10));
INSERT INTO @account_users(account_id, user_id, role)
VALUES(1, 1, 'user1_role'),
      (1, 2, 'user2_role'),
      (2, 1, 'user1_role'),
      (3, 3, 'user3_role'),
      (3, 4, 'user4_role');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    相关资源
    最近更新 更多