考虑以下三个表:
t1(id,name,cDate,foo,…)
t2(id,name,cDate,bar,…)
t3(id,name,cDate,other,…)
这些表代表一些独立的实体。我需要在网站主页上显示它们,无论它们在按创建日期排序的列表中的类型(cDate)。
rows
---
t1
t2
t2
t3
t2
t1
目前我已经通过联合创建了一个视图(或子查询)的一些共享列和一个用于表名的辅助列:v1(id,cDate,tableName)
来选择它们按cDAte排序。之后,我在每个表上查询以获取表的行,并将结果合并到PHP数组中并将它们发送回查看。但是我认为它不那么高效和干净。有没有更好的方法?
输出是一个随时可用的资源,包含三个表格的所有数据。
答案 0 :(得分:3)
这是我怎么做的。非常简单的联合,然后加入预先订购的套装。
SELECT * FROM
(
SELECT 't1' as source, pid, cDate from t1
UNION
SELECT 't2' as source, pid, cDate from t2
UNION
SELECT 't3' as source, pid, cDate from t3
ORDER BY cDate DESC
)
LEFT JOIN t1 ON (source='t1' AND pid=t1.id)
LEFT JOIN t3 ON (source='t2' AND pid=t2.id)
LEFT JOIN t3 ON (source='t3' AND pid=t3.id)
答案 1 :(得分:3)
MySQL UNION运算符允许您将多个表中的两个或多个结果集合并到一个结果集中。 有些规则需要遵循mysql UNION
列数出现在相应的SELECT语句中 必须是平等的。
列出现在相应的位置 每个SELECT语句必须具有相同的数据类型或至少 可转换数据类型。
默认情况下,UNION运算符会从结果中删除重复的行。
(SELECT t1.id,t1.name, t1.Cdate ..... from t1 as t1)
UNION
(SELECT t2.id,t2.name, t2.Cdate ..... from t2 as t2)
UNION
SELECT t3.id,t3.name, t3.Cdate ..... from t3 as t3)
ORDER BY id,name
确保所有列名称都应具有相同名称的别名。否则,MySQL使用第一个SELECT语句中的列名作为输出的标签。
答案 2 :(得分:3)
In PHP $x = 20; $limit = "LIMIT ".$x; $sql = "SELECT * FROM( SELECT id, name, cDate FROM t1 $limit UNION SELECT id,name,cDate from t2 $limit UNION SELECT id, name, cDate from t3 $limit )ORDER BY cDate DESC $limit"; $result = mysql_query($sql);
答案 3 :(得分:3)
作为对@John Green答案的改进,我使用COALESCE函数创建了SQL fiddle,它返回第一个非null参数:
SELECT COALESCE(t1.id, t2.id, t3.id) id
, COALESCE(t1.name, t2.name, t3.name) name
, COALESCE(t1.cDate, t2.cDate, t3.cDate) cDate
, COALESCE(t1.foo, t2.bar, t3.other) uniqueField
FROM (
SELECT 't1' AS source, id FROM t1
UNION
SELECT 't2' AS source, id FROM t2
UNION
SELECT 't3' AS source, id FROM t3
) ad
LEFT JOIN t1 ON ad.id = t1.id AND ad.source = 't1'
LEFT JOIN t2 ON ad.id = t2.id AND ad.source = 't2'
LEFT JOIN t3 ON ad.id = t3.id AND ad.source = 't3'
ORDER BY cDate
使用此方法的优点是,您可以按照业务规则的要求组合所有表中不常见的字段,如uniqueField
答案 4 :(得分:2)
保存其中一个实体时,不仅要将其保存在表本身中,还要在共享引用表中创建引用实体。该表中的行将在创建日期自动排序。
您知道必须从每个表中收集哪些数据。如果显示的所需数据对于每个不同的实体是相同的,那么您可以对共享参考表进行简单设计。要获取所需的所有信息,只需查询表的最后20行。完成。原始实体的主键是例如共享引用表中的第二列。
如果要显示的数据不同,那么共享引用表的设计可能会变得更加困难,但原理是相同的:在将每个实体存储在自己的表中的同时将数据存储在该表中。
在PHP站点的视图中,您将读取共享引用表的每一行,并在从行中读取信息时创建相应的链接。在行中,您将获得主键的值和实体的名称(从不使用表名!)。
答案 5 :(得分:2)
这个问题的主要困难在于您可能会忘记的部分:从三个表中获取所有结果是一件容易的事。你选择,联盟,订购。
但是如果你想要一种有效的方法来检索所有结果,那么获取属于3个表的最新20个来源是一件比较困难的事情。
在这种情况下更好的是:
第一个解决方案:使用扁平的“桌子”重新设计您的桌子。 该表将包含三个表中的所有字段。
第二个解决方案:使用继承建模重新设计表。主表将包含公共字段,类型字段将通知您其他信息所在的位置。
第三种解决方案:如果您选择使用当前型号,则必须在UNION之前使用LIMIT。
像这样:
SELECT * FROM (
SELECT id, name, cDate FROM t1 ORDER BY cDate DESC LIMIT 20
UNION
SELECT id, name, cDate from t2 ORDER BY cDate DESC LIMIT 20
UNION
SELECT id, name, cDate from t3 ORDER BY cDate DESC LIMIT 20
) ORDER BY cDate DESC LIMIT 20;