单个查询从具有不同列的多个表中获取记录
Single Query to fetch records from multiple tables with different columns
我有 2 个不同的 table 想要在单个查询中获取记录。目前,我正在使用 2 个查询,然后合并数组结果,然后显示记录。以下是我当前的代码:
$db = JFactory::getDbo();
$query1 = "SELECT a.id as cId, a.title, a.parent_id,a.level FROM `categories` AS a WHERE ( a.title LIKE '%keyword%' )";
$result1 = $db->setQuery($query1)->loadObjectlist(); //gives selected records
$query2 = "SELECT b.id as indId, b.indicator , b.cat_id, b.subcat_id, b.section_id FROM `indicator` as b WHERE ( b.indicator LIKE '%keyword%' )";
$result2 = $db->setQuery($query2)->loadObjectlist(); //gives selected records
$_items = array_merge($result1,$result2); //then using $_items in php code to display the data
它在 Joomla 中,但我只想知道我们如何将这两个查询合并为一个。我尝试了以下但它给出了来自类别 table.
的第一个查询的结果
(SELECT id as cId, title, parent_id,level, NULL FROM `categories` WHERE ( title LIKE '%birth%' ))
UNION ALL
(SELECT id as indId, indicator , cat_id, subcat_id, section_id FROM `indicator` WHERE ( indicator LIKE '%birth%' ))
期望输出:
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| cId | title | parent_id | level | indId | indicator | cat_id | subcat_id | section_id
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 2874 | births | 2703 | 2 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 13 | birth weight| 12 | 3 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 135 | resident births| 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 189 | births summary | 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
以上输出将有助于获得正确的分页记录。我尝试使用 join,但 JOIN 需要 ON clause
中的公共列。在这里,我想要所有的列及其值。基本上我想在一个查询中合并 2 table 记录。任何帮助将不胜感激
这是一个例子,
有多种方法可以做到这一点,具体取决于您真正想要的。没有通用柱,您需要决定是要引入通用柱还是获取产品。
假设您有两个 table:
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
忘记实际的列,因为在这种情况下您很可能有 customer/order/part 关系;我只是使用这些专栏来说明执行此操作的方法。
笛卡尔积将匹配第一行中的每一行 table 与第二行中的每一行:
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
这可能不是您想要的,因为 1000 个零件和 100 个客户会导致 100,000 行包含大量重复信息。
或者,您可以使用联合来输出数据,尽管不是并排的(您需要确保列类型在两个 select 之间兼容,方法是table 列在 select 中兼容或强制它们):
> select id as pid, desc, '' as cid, '' as name from parts
union
select '' as pid, '' as desc, id as cid, name from custs;
pid desc cid name
--- ---- --- ----
101 Bob
102 Paul
1 Sprocket
2 Flange
在某些数据库中,您可以使用 rowid/rownum 列或伪列来并排匹配记录,例如:
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
代码类似于:
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
它仍然像笛卡尔积,但where
子句限制了行组合形成结果的方式(所以根本不是笛卡尔积,真的) .
我还没有为此测试 SQL,因为它是我选择的 DBMS 的局限之一,而且我不认为在经过深思熟虑的模式中需要它。由于 SQL 不保证它生成数据的顺序,每次查询时匹配都会改变,除非你有 specific 关系或 order by
条款。
我认为理想的做法是在两个 table 中添加一列来指定关系是什么。如果没有真正的关系,那么您可能没有必要尝试将它们与 SQL.
并排放置
正如@Sinto 所建议的 union
的答案和下面的虚拟列名是整个正确的查询:
(SELECT id as cId, title, parent_id,level, NULL as indId, NULL as indicator , NULL as cat_id, NULL as subcat_id, NULL as section_id FROM `jm_categories` WHERE ( title LIKE '%births%' )) UNION ALL (SELECT NULL as cId, NULL as title, NULL as parent_id,NULL as level, id as indId, indicator , cat_id, subcat_id, section_id FROM `jm_indicator_setup` WHERE ( indicator LIKE '%births%' ))
我们必须匹配两个表中的列名,以便我们获得组合记录。
我有 2 个不同的 table 想要在单个查询中获取记录。目前,我正在使用 2 个查询,然后合并数组结果,然后显示记录。以下是我当前的代码:
$db = JFactory::getDbo();
$query1 = "SELECT a.id as cId, a.title, a.parent_id,a.level FROM `categories` AS a WHERE ( a.title LIKE '%keyword%' )";
$result1 = $db->setQuery($query1)->loadObjectlist(); //gives selected records
$query2 = "SELECT b.id as indId, b.indicator , b.cat_id, b.subcat_id, b.section_id FROM `indicator` as b WHERE ( b.indicator LIKE '%keyword%' )";
$result2 = $db->setQuery($query2)->loadObjectlist(); //gives selected records
$_items = array_merge($result1,$result2); //then using $_items in php code to display the data
它在 Joomla 中,但我只想知道我们如何将这两个查询合并为一个。我尝试了以下但它给出了来自类别 table.
的第一个查询的结果(SELECT id as cId, title, parent_id,level, NULL FROM `categories` WHERE ( title LIKE '%birth%' ))
UNION ALL
(SELECT id as indId, indicator , cat_id, subcat_id, section_id FROM `indicator` WHERE ( indicator LIKE '%birth%' ))
期望输出:
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| cId | title | parent_id | level | indId | indicator | cat_id | subcat_id | section_id
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 2874 | births | 2703 | 2 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| 13 | birth weight| 12 | 3 | null | null | null | null | null |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 135 | resident births| 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
| null | null | null | null | 189 | births summary | 23 | 25 | 1 |
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+
以上输出将有助于获得正确的分页记录。我尝试使用 join,但 JOIN 需要 ON clause
中的公共列。在这里,我想要所有的列及其值。基本上我想在一个查询中合并 2 table 记录。任何帮助将不胜感激
这是一个例子,
有多种方法可以做到这一点,具体取决于您真正想要的。没有通用柱,您需要决定是要引入通用柱还是获取产品。
假设您有两个 table:
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
忘记实际的列,因为在这种情况下您很可能有 customer/order/part 关系;我只是使用这些专栏来说明执行此操作的方法。
笛卡尔积将匹配第一行中的每一行 table 与第二行中的每一行:
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
这可能不是您想要的,因为 1000 个零件和 100 个客户会导致 100,000 行包含大量重复信息。
或者,您可以使用联合来输出数据,尽管不是并排的(您需要确保列类型在两个 select 之间兼容,方法是table 列在 select 中兼容或强制它们):
> select id as pid, desc, '' as cid, '' as name from parts
union
select '' as pid, '' as desc, id as cid, name from custs;
pid desc cid name
--- ---- --- ----
101 Bob
102 Paul
1 Sprocket
2 Flange
在某些数据库中,您可以使用 rowid/rownum 列或伪列来并排匹配记录,例如:
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
代码类似于:
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
它仍然像笛卡尔积,但where
子句限制了行组合形成结果的方式(所以根本不是笛卡尔积,真的) .
我还没有为此测试 SQL,因为它是我选择的 DBMS 的局限之一,而且我不认为在经过深思熟虑的模式中需要它。由于 SQL 不保证它生成数据的顺序,每次查询时匹配都会改变,除非你有 specific 关系或 order by
条款。
我认为理想的做法是在两个 table 中添加一列来指定关系是什么。如果没有真正的关系,那么您可能没有必要尝试将它们与 SQL.
并排放置正如@Sinto 所建议的 union
的答案和下面的虚拟列名是整个正确的查询:
(SELECT id as cId, title, parent_id,level, NULL as indId, NULL as indicator , NULL as cat_id, NULL as subcat_id, NULL as section_id FROM `jm_categories` WHERE ( title LIKE '%births%' )) UNION ALL (SELECT NULL as cId, NULL as title, NULL as parent_id,NULL as level, id as indId, indicator , cat_id, subcat_id, section_id FROM `jm_indicator_setup` WHERE ( indicator LIKE '%births%' ))
我们必须匹配两个表中的列名,以便我们获得组合记录。