2

现在我正在努力将我的网站扩展到新功能。我想启用来自不同来源的通知。类似于 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 中对所有内容进行排序会效率低下。做这个的最好方式是什么?如果我要使用联合之类的东西,我需要一种方法来区分通知类型,因为 user_updates 和 course_updates 可以在更新中存储对同一列的引用。有任何想法吗?

4

3 回答 3

1

你可能根本不需要updates桌子。您可以在course_updatesuser_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()在一个列中的分隔字符串(使用)中(让我们称之为details)很方便,注入一列来区分更新输入(让我们称之为obj_type)并使用UNION ALL

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

样本输出:

| 对象类型 | 身份证 | 时间戳 | 详情 |
-------------------------------------------------- ----------------------
| C | 3 | 2013 年 7 月 30 日 22:00:00+0000 | 3|课程3|主题3|1414 |
| 你 | 2 | 2013 年 7 月 11 日 14:00:00+0000 | 1|名称1|FB名称1 |
| 你 | 2 | 2013 年 7 月 11 日 14:00:00+0000 | 3|名称3|FB 名称3 |
...

这是SQLFiddle演示

explode然后,您可以在 php.ini 中迭代结果集时轻松详细说明值。

于 2013-08-02T01:28:46.320 回答
0

如果你要合并这两个表,你需要记住两件事:

  1. 理想情况下,列数应相同
  2. 应该有一种方法来区分数据的来源。

这是您可以执行此操作的一种方法:

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,但您可以添加它,请记住,您必须向用户选择语句添加一些虚拟文本,以确保两个查询返回相同的行数。请注意,如果有涉及用户和课程的更新,它将出现两次。

您还可以排序type以区分用户和课程数据。

于 2013-08-02T03:07:05.317 回答
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;
于 2013-08-02T00:51:08.227 回答