【问题标题】:SQL query returning empty and I can't figure out why?SQL 查询返回空,我不知道为什么?
【发布时间】:2021-06-15 04:21:38
【问题描述】:

我有这个复杂的查询在技术上是可行的,但最近它的“开发者_”部分从必需变为可选。现在,当缺少特定数据时,查询返回空。

    $sql = "SELECT    a.*,
                      b.title AS manufacturer_title,
                      b.slug AS manufacturer_slug,
                      b.url AS manufacturer_url,
                      c.fname AS manufacturer_logo,
                      d.title AS region_title,
                      e.title AS game_title,
                      e.slug AS game_slug,
                      f.title AS developer_title,
                      f.slug AS developer_slug,
                      f.url AS developer_url,
                      g.fname AS developer_logo,
                      h.title AS exclusive_title,
                      h.slug AS exclusive_slug,
                      h.url AS exclusive_url,
                      i.fname AS exclusive_logo,
                      j.title AS edition_title,
                      k.title AS edition_parent_title
            FROM      catalog_items AS a
            JOIN      catalog_franchises AS b ON a.manufacturer_id = b.franchise_id
            LEFT JOIN catalog_images AS c ON b.logo_id = c.img_id
            JOIN      catalog_regions AS d ON a.region_id = d.region_id
            JOIN      catalog_franchises AS e ON a.game_id = e.franchise_id
            JOIN      catalog_franchises AS f ON a.developer_id = f.franchise_id
            LEFT JOIN catalog_images AS g ON f.logo_id = g.img_id
            LEFT JOIN catalog_franchises AS h ON a.exclusive_id = h.franchise_id
            LEFT JOIN catalog_images AS i ON h.logo_id = i.img_id
            LEFT JOIN catalog_editions AS j ON a.edition_id = j.edition_id
            LEFT JOIN catalog_editions AS k ON j.parent_id = k.edition_id
            WHERE     a.item_id = :item_id
                      AND a.valid = TRUE
                      AND b.valid = TRUE
                      AND (c.valid = TRUE OR c.fname IS NULL)
                      AND d.valid = TRUE
                      AND e.valid = TRUE
                      AND f.valid = TRUE
                      AND (g.valid = TRUE OR g.fname IS NULL)
                      AND (h.valid = TRUE OR h.title IS NULL)
                      AND (i.valid = TRUE OR i.fname IS NULL)
                      AND (j.valid = TRUE OR j.title IS NULL)
                      AND (k.valid = TRUE OR k.title IS NULL)
            GROUP BY  a.item_id";

我尝试将AND f.valid = TRUE 修改为各种内容:

AND (f.valid = TRUE OR f.title IS NULL)

AND (f.valid = TRUE OR a.developer_id IS NULL)

但似乎没有任何作用。我需要修改什么,以便所有对“developer_”的引用都是可选的?

【问题讨论】:

  • 这是一个很好的例子,说明为什么 使用任意字母作为表别名。使用表名的缩写!
  • 我认为您需要将其更改为 LEFT Join - 来自文档In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents (they can replace each other)
  • 为什么不简单的问题
  • 请注意,这些都是内部连接(有点)
  • 具体来说,JOIN to f需要改为LEFT JOIN,对f.valid的检查需要OR ... IS NULL条件之一。

标签: php mysql sql database pdo


【解决方案1】:

让我们整理一下您的 JOIN 和 WHERE 内容,然后再使用一个 LEFT JOIN。通过将 x.valid = TRUE 项目置于 ON 条件下,OR ... IS NULL 部门的事情变得更干净了。

为了在结果集中保留 catalog_franchises.franchise_id 与任何 catalog_items.developer_id 不匹配的行,请将您的 JOIN 更改为 LEFT JOIN。

SELECT      a.*, b.many columns, c.many columns ... etc ...
  FROM      catalog_items AS a
  JOIN      catalog_franchises AS b     ON a.manufacturer_id = b.franchise_id
                                       AND b.valid = TRUE
  LEFT JOIN catalog_images AS c         ON b.logo_id = c.img_id
                                       AND c.valid = TRUE
  JOIN      catalog_regions AS d        ON a.region_id = d.region_id
                                       AND d.valid = TRUE
  JOIN      catalog_franchises AS e     ON a.game_id = e.franchise_id
                                       AND e.valid = TRUE
  /* use LEFT JOIN on this next line to allow developer_id to not match */
  LEFT JOIN catalog_franchises AS f     ON a.developer_id = f.franchise_id
                                       AND f.valid = TRUE
  LEFT JOIN catalog_images AS g         ON f.logo_id = g.img_id
                                       AND g.valid = TRUE
  ... etc etc etc  ...
  WHERE a.item_id = :item_id
    AND a.valid = TRUE
  GROUP BY  a.item_id  /* this wrongly chooses arbitrary values from aliases b-k */

您误用了 MySQL 的 notorious nonstandard extension to GROUP BY。当您开始获取结果时,它可能会导致结果集中出现一些混乱。

【讨论】:

  • LEFT JOIN 似乎是我忽略的,谢谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 2015-06-01
相关资源
最近更新 更多