SQL 查询返回空,我不明白为什么?
SQL query returning empty and I can't figure out why?
我有一个技术上可行的复杂查询,但最近它的“developer_”部分从必需变为可选。现在,当缺少特定数据时,查询 returns 为空。
$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_”的引用都可以是可选的?
让我们整理一下您的 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。当您开始获取结果时,它可能会导致您的结果集出现一些混乱。
我有一个技术上可行的复杂查询,但最近它的“developer_”部分从必需变为可选。现在,当缺少特定数据时,查询 returns 为空。
$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_”的引用都可以是可选的?
让我们整理一下您的 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。当您开始获取结果时,它可能会导致您的结果集出现一些混乱。