如何加入多个表?

时间:2009-03-28 19:10:08

标签: sql sql-server join

我有以下表格(和示例值):

**user:**
user_id (1, 2, 3)
username (john33, reddiamond...)
password (pass1, pass2...)

**session:**
session_id (4,5, 6)
user_id (1, 2, 3)

**activity**
activity_id (1, 2)
name (running, walking...)

**user_activity**
user_activity_id (1, 2, 3, 4, 5)
session_id (4, 5)
activity_id (1, 2)

所有具有相同名称的列都是相关的。在表user_activity中,有些行描述了会话的活动,活动是指用户。

但是,我想获得描述用户当前正在做什么的表:

**result**
username(john33)
activity.name(walking)

获取结果表的SQL语句是什么?

(我正在使用MSSQL)。

5 个答案:

答案 0 :(得分:7)

SELECT u.username, a.name
FROM user_activity ua
INNER JOIN session s
ON ua.session_id = s.session_id
INNER JOIN user u
ON s.user_id = u.user_id
INNER JOIN activity a
ON ua.activity_id = a.activity_id

答案 1 :(得分:2)

我认为session.session_iduser_activity.user_activity_idIDENTITY列,因此它们会单调递增。因此它们是独一无二的,最大的值表示最近的条目。

所以你需要做的是:

  • usersession中具有最大session_id值的相应行匹配(即找不到具有相同user_id的其他行,并且更大session_id)。

  • 然后将session中的该行与user_activity中具有最大user_activity_id的相应行匹配。

  • 然后将user_activity中的该行与activity中的对应行匹配,以获得name

这是一个应该实现这一目标的查询(虽然我还没有测试过):

SELECT u.username, a.name
FROM user u
 JOIN session s1 ON (u.user_id = s1.user_id)
 LEFT OUTER JOIN session s2 ON (u.user_id = s2.user_id 
   AND s1.session_id < s2.session_id)
 JOIN user_activity ua1 ON (ua1.session_id = s1.session_id)
 LEFT OUTER JOIN user_activity ua2 ON (ua2.session_id = s1.session_id 
   AND ua1.user_activity_id < ua2.user_activity_id)
 JOIN activity a ON (a.activity_id = ua1.activity_id)
WHERE s2.session_id IS NULL AND ua2.user_activity_id IS NULL;

这是另一种形式的查询,应该得到相同的结果,并且可能更容易可视化:

SELECT u.username, a.name
FROM user u
 JOIN session s1 ON (u.user_id = s1.user_id)
 JOIN user_activity ua1 ON (ua1.session_id = s1.session_id)
 JOIN activity a ON (a.activity_id = ua1.activity_id)
WHERE s1.session_id = (
     SELECT MAX(s2.session_id) FROM session s2 
     WHERE s2.user_id = u.user_id)
 AND ua1.user_activity_id = (
     SELECT MAX(ua2.user_activity_id) FROM user_activity ua2 
     WHERE ua2.session_id = s1.session_id);

答案 2 :(得分:2)

我从您对所需结果的陈述中假设您想要找到当前活动的foreach用户。我还假设用户可能有很多会话,并且当前会话是session_id最高的会话。

当然,如果每个用户只有一个会话,每个用户只有一个user_activity记录,那么这不是问题,您接受的答案也没问题。

这里的关键问题是确定每个用户的最新user_activity记录,并使用它来进入活动。

这可以通过以下方式完成: -

SELECT  u.username,  
        a.name  
FROM    user_activity AS ua  
JOIN    session AS s ON ua.session_id = s.session_id  
JOIN    user AS u ON u.user_id = s.user_id  
JOIN    activity AS a ON ua.activity_id = a.activity_id  
WHERE   ua.user_activity_id IN (  
          SELECT  MAX(ua2.user_activity_id)  
          FROM    user_activity AS ua2  
          JOIN    session AS s2 ON ua2.session_id = s2.session_id  
          GROUP BY s2.user_id);  

以下测试数据证明了SQL。它创建了4个用户和4个活动,然后为每个做家务的用户创建了user_activity记录。然后它将三个用户设置为正常活动。

INSERT INTO user (username) VALUES ('sneezy');  
INSERT INTO user (username) VALUES ('grumpy');  
INSERT INTO user (username) VALUES ('happy');  
INSERT INTO user (username) VALUES ('snow_white');  

INSERT INTO session (user_id) SELECT u.user_id FROM user AS u;  

INSERT INTO activity(name) VALUES ("Sneezing");  
INSERT INTO activity(name) VALUES ("Frowning");  
INSERT INTO activity(name) VALUES ("Smiling");  
INSERT INTO activity(name) VALUES ("Housework");  

INSERT INTO user_activity (session_id, activity_id)  
SELECT s.session_id, a.activity_id  
FROM   session AS s JOIN activity AS a  
WHERE   a.name IN ("Housework");  

INSERT INTO user_activity(session_id, activity_id)  
SELECT  s.session_id, a.activity_id  
FROM    session AS s  
JOIN    USER as u ON s.user_id = u.user_id  
JOIN    activity AS a ON a.name = 'Sneezing'  
WHERE   u.username = 'sneezy' ;  

INSERT INTO user_activity(session_id, activity_id)  
SELECT  s.session_id, a.activity_id  
FROM    session AS s  
JOIN    USER as u ON s.user_id = u.user_id  
JOIN    activity AS a ON a.name = 'Frowning'  
WHERE   u.username = 'grumpy' ;  

INSERT INTO user_activity(session_id, activity_id)  
SELECT  s.session_id, a.activity_id  
FROM    session AS s  
JOIN    USER as u ON s.user_id = u.user_id  
JOIN    activity AS a ON a.name = 'Smiling'  
WHERE   u.username = 'happy' ;  

这会产生以下结果

  snow_white Housework
  sneezy     Sneezing
  grumpy     Frowning
  happy      Smiling

答案 3 :(得分:1)

我认为它会是这样的:

select u.username, a.name
from user u
join session s on u.user_id = s.user_id
join user_activity ua on ua.session_id = s.session_id
join activity a on a.activity_id = ua.activity_id

答案 4 :(得分:-2)

SELECT user.user_name,
activity.name1
FROM activity 

INNER JOIN user 
INNER JOIN session 
  ON user.user_id = session.user_id

INNER JOIN user_activity 
  ON session.session_id = user_activity.session_id 
  ON activity.activity_id = user_activity.activity_id