php - 即使记录不存在于另一个表中,也显示 JOIN 查询中的 MySQL 行

标签 php mysql

我有一个 PHP/MySQL 应用程序,它连接到一个数据库,该数据库具有 2 个名为 'displays' 的表和 'display_substances' .这些表的结构如下:

mysql> DESCRIBE displays;
+----------+----------------------+------+-----+---------+----------------+
| Field    | Type                 | Null | Key | Default | Extra          |
+----------+----------------------+------+-----+---------+----------------+
| id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| label    | varchar(255)         | NO   |     | NULL    |                |
+----------+----------------------+------+-----+---------+----------------+

mysql> DESCRIBE display_substances;
+--------------+-----------------------+------+-----+---------+----------------+
| Field        | Type                  | Null | Key | Default | Extra          |
+--------------+-----------------------+------+-----+---------+----------------+
| id           | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| display_id   | smallint(5) unsigned  | NO   | MUL | NULL    |                |
| substance_id | mediumint(8) unsigned | NO   | MUL | NULL    |                |
| value        | text                  | NO   |     | NULL    |                |
+--------------+-----------------------+------+-----+---------+----------------+

还有一个'substances'表和外键 display_substances.substance_idsubstances.id 有关.

'displays'表正好包含 400 行和 'display_substances'大约 150 万行。

我想做的是输出所有 400 'displays.label'放入 HTML 表格中,然后在第二列中显示 'display_substances.value' .由于该页面一次仅显示 1 种物质,因此还需要基于 'display_substances.substance_id' .

我遇到的问题是记录只存在于 'display_substances' 中当我们有适当的可用数据时'displays' .但是,输出必须显示来自 'displays'所有 记录然后在 'display_substances' 中没有相应记录的任何内容旁边放置文本“未列出” .

我已经完成了以下操作 - 这给了我想要的输出 - 但有缺陷(请参阅下面的“问题”部分)。

  1. 选择“显示”表中的所有记录:SELECT label FROM displays ORDER BY label ASC

  2. 全选 display_substances.display_id对于当前显示的物质:SELECT display_id FROM display_substances WHERE substance_id = 1 (假设 1 是当前物质 ID)。将 ID 存储在名为 $display_substances 的数组中

  3. 遍历 (1) 并使用 in_array()查看 (2) 是否存在:

    foreach ($displays as $display) { // step (1)
        $display_substances = // See step (2)
        if (in_array($display['id'], $display_substances)) { // step (3)
            $display_value = // See step (4)
        } else {
            $display_value = 'Not listed';
        }
        $output[] = ['display_label' => $display['label'], 'display_value' => $display_value]; // See step (5)
    }
    
  4. 如果in_array()条件为真,然后我进行查询以选择“display_substances”的相应行:SELECT value FROM display_substances WHERE display_id = $display['id'] AND substance_id = 1

  5. $output变量缓冲所有数据,然后将其输出到 HTML 表中。我得到的输出正是我想要的。

问题

虽然输出是正确的,但我想将这一切作为 1 个查询(如果可能的话)来完成,因为我需要添加功能以通过 displays.label 进行搜索。或 display_substances.value - 或两者的结合。第一部分相当简单,因为我可以将 (1) 中的查询修改为:

SELECT label FROM displays WHERE label LIKE '% Foo %' ORDER BY label ASC

但是,这不会生成display_substances.value可搜索,因为当我们到达步骤 (3) 时,我们正在处理单行 display_substances不是整张 table 。我看不出如何以不同的方式编写它,因为我们需要知道该表中存在哪些记录用于加载的物质。

我还编写了以下查询 - 但这个不会起作用,因为它遗漏了任何“未列出”的内容:

SELECT displays.label, display_substances.`value` FROM displays JOIN display_substances ON displays.id = display_substances.display_id WHERE display_substances.substance_id = 1

我已阅读 How do I get the records from the left side of a join that do not exist in the joined table?但这没有帮助。

进一步说明

假设 display_substances 中有 120 行对应于物质 ID 1 ( WHERE display_substances.substance_id = 1 )。 查询的输出应始终为 400 行。在这个例子中,120 应该有 display_substances.value在它们旁边,280 应该有文本“未列出”。

最佳答案

您需要一个左联接和一个 group_concat 来获取左表中的所有记录以及分组依据。

但请记住 group_concat 有一个限制,因此您可能无法获得所有关联的记录,因为它通常用于小字段,但由于您的值有一个“文本”字段,因此您很可能会达到限制

无论如何这是查询

SELECT d.*, GROUP_CONCAT(ds.value) `substances`
FROM displays `d`
LEFT JOIN display_substances `ds` ON `d`.`id` = `ds`.`display_id`
GROUP BY `d`.`id`

如果我理解正确的话,这样的事情可能会奏效

SELECT d.*, IFNULL((SELECT GROUP_CONCAT(value) FROM display_substances `ds` WHERE `ds`.`display_id` = `d`.`id` GROUP BY `ds`.`display_id`), 'Not Listed') `substances`
FROM displays `d`

您可以更新位置并添加 AND substance_id = 1

关于php - 即使记录不存在于另一个表中,也显示 JOIN 查询中的 MySQL 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52933192/

相关文章:

Javascript无法运行表单的幻灯片效果

PHP 变量与数组

php - 即使我知道参数的类型,我还需要准备语句吗?

php - Symfony2 : How to inject ALL parameters in a service?

php - 可选的 LIMIT 用于使用 PDO 抓取所有帖子的功能

php - Laravel 4 : @include causes Apache (httpd. exe) 崩溃(在 Windows 上)

mysql - 将两个表合并在一起,其中所有列都不匹配

mysql - 其他表中的 AVG 连接结果

c# - 如何在 Entity Framework 连接字符串中设置转换零日期时间

sql - MySql:创建表和外键的简单问题