单个查询以从具有不同列的多个表中获取记录

时间:2017-07-12 07:24:05

标签: php mysql union-all

我有两个不同的表,希望在单个查询中获取记录。目前,我使用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中我只是想知道如何将这两个查询合并为一个。我尝试了以下内容,但它从类别表中提供了第一个查询的结果。

(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个表记录。任何帮助将不胜感激

2 个答案:

答案 0 :(得分:2)

这是一个例子,

有很多方法可以执行此操作,具体取决于您 想要的内容。如果没有常用列,则需要确定是要引入公共列还是获取产品。

我们假设你有两张桌子:

parts:              custs:
+----+----------+   +-----+------+
| id | desc     |   |  id | name |
+----+----------+   +-----+------+
|  1 | Sprocket |   | 100 | Bob  |
|  2 | Flange   |   | 101 | Paul |
+----+----------+   +-----+------+

忘记实际列,因为在这种情况下,您很可能拥有客户/订单/部件关系;我刚刚使用这些专栏来说明这些方法。

笛卡尔积将匹配第一个表中的每一行与第二个中的每一行:

> 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行,并且有大量重复信息。

或者,您可以使用union来输出数据,但不能并排(您需要确保两种选择之间的列类型兼容,方法是使表列兼容或在选择中强制他们:

> 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不保证其生成数据的顺序,因此除非您具有特定的关系或order by子句,否则每次执行查询时匹配都会更改。

我认为理想的做法是在两个表中添加一个列来指定关系。如果没有真正的关系,那么你可能没有尝试将它们与SQL并排放置。

答案 1 :(得分:0)

正如@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%' ))

我们必须匹配两个表中的列名,以便我们将记录作为一个组合。