我有以下表格(和示例值):
**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)。
答案 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_id
和user_activity.user_activity_id
是IDENTITY
列,因此它们会单调递增。因此它们是独一无二的,最大的值表示最近的条目。
所以你需要做的是:
将user
与session
中具有最大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