现在我正在努力将我的网站扩展到新功能。我想启用来自不同来源的通知。类似于facebook上的群组和人物。这是我现在的表格布局。
course_updates
id | CRN (id of course) | update_id
------------------------------------
courses
id | course_name | course_subject | course_number
-------------------------------------------------
users
id | name | facebook_name
---------------------------------------------------
user_updates
id | user_id | update_id
------------------------
updates
id | timestamp | updateObj
---------------------------
我希望能够做的是在一个查询中使用course_update和user_updates,并将它们与更新以及表的正确信息一起加入。所以对于course_updates我想要course_name,course_subject等,而对于user_updates,我想要用户名和facebook名称。这老实说可能属于两个单独的查询,但我想按更新表的时间戳排列所有内容,我觉得在php中排序一切都效率低下。做这个的最好方式是什么?我需要一种方法来区分通知类型,如果我使用像union这样的东西,因为user_updates和course_updates可以存储对更新中同一列的引用。有什么想法吗?
答案 0 :(得分:1)
您可能根本不需要updates
表。您可以将时间戳列添加到course_updates
和user_updates
表
CREATE TABLE course_updates
(
`id` int,
`CRN` int,
`timestamp` datetime -- or timestamp type
);
CREATE TABLE user_updates
(
`id` int,
`user_id` int,
`timestamp` datetime -- or timestamp type
);
现在要获得所有更新的有序和列级统一结果集,您可能会发现在一列中使用分隔字符串(使用CONCAT_WS()
)打包每种更新类型的更新详细信息很方便(让我们称之为{ {1}}),注入一列来区分更新类型(让我们称之为details
)并使用obj_type
UNION ALL
示例输出:
| OBJ_TYPE | ID | TIMESTAMP | DETAILS | ------------------------------------------------------------------------- | C | 3 | July, 30 2013 22:00:00+0000 | 3|Course3|Subject3|1414 | | U | 2 | July, 11 2013 14:00:00+0000 | 1|Name1|FB Name1 | | U | 2 | July, 11 2013 14:00:00+0000 | 3|Name3|FB Name3 | ...
这是 SQLFiddle 演示
然后,当您在php中迭代结果集时,可以轻松地SELECT 'C' obj_type, u.id, u.timestamp,
CONCAT_WS('|',
c.id,
c.course_name,
c.course_subject,
c.course_number) details
FROM course_updates u JOIN courses c
ON u.CRN = c.id
UNION ALL
SELECT 'U' obj_type, u.id, u.timestamp,
CONCAT_WS('|',
s.id,
s.name,
s.facebook_name) details
FROM user_updates u JOIN users s
ON u.user_id = u.id
ORDER BY timestamp DESC
详细说明值。
答案 1 :(得分:0)
我认为您不应该在查询中将这两个概念(用户和课程)混合在一起。它们具有不同数量的列并且与不同的概念相关。
我认为你真的应该使用两个查询。一个用户,一个用于课程。
SELECT courses.course_name, courses.course_subject, courses.course_number,
updates.updateObj,updates.timestamp
FROM courses, updates, course_updates
WHERE courses.id = course_updates.course_id
AND course_updates.udpate_id = updates.id
ORDER BY updates.timestamp;
SELECT users.name,users.facebook_name,updates.updateObj,updates.timestamp
FROM users ,updates, user_updates
WHERE users.id = user_updates.user_id
AND user_updates.update_id = updates.id
ORDER BY updates.timestamp;
答案 2 :(得分:0)
如果你要合并两个表,你需要记住两件事:
以下是一种可以做到这一点的方法:
SELECT * FROM
(SELECT courses.course_name as name, courses.course_subject as details,
updates.updateObj as updateObj, updates.timestamp as timestamp,
"course" as type
FROM courses, updates, course_updates
WHERE courses.id = course_updates.course_id
AND course_updates.udpate_id = updates.id)
UNION ALL
SELECT users.name as name,users.facebook_name as details,
updates.updateObj as updateObj,updates.timestamp as timestamp,
"user" as type
FROM users ,updates, user_updates
WHERE users.id = user_updates.user_id
AND user_updates.update_id = updates.id) as out_table
ORDER BY out_table.timestamp DESC
type
可让您区分用户和课程更新,前端可以使用它来为行添加不同的颜色。 course_id
没有出现在此,但您可以添加它,请记住,您必须向用户select语句添加一些虚拟文本,以确保两个查询返回相同的行数。请注意,如果有涉及用户和课程的更新,它将出现两次。
您也可以按type
订购,以区分用户和课程数据。