我正在开发一个产品数据库(PDB),既可用于网上商店,也可用作ERP系统中的文章。大多数数据直接来自我们的供应商作为CSV文件,我们添加了覆盖某些字段的选项,这导致了一个表结构,我无法弄清楚如何有效地查询。
本质上,表结构由两个表组成,article和extended_article,其中最后一个表包含一个名为parent_article_code的字段,用于将女性文章组合成男性用于显示目的。并非所有文章都包含extended_articles,并且并非所有包含extended_articles的文章都在parent_article_code中有值。
我需要执行一个查询,返回所有带匹配的文章,但只显示父文章,其中父文章或子文章与查询匹配。这是一个非常简单的表格版本,我还将添加一个查询来显示数据的实际结构。
文章表:
-------------------------------------------------------------------------
| id | code | name | description |
| 1 | 029320 | T-shirt | Nice t-shirt with awsome logo |
| 2 | 029321 | T-shirt Lady | Nice t-shirt with awsome logo |
| 3 | 029322 | Sweatshirt | Nice sweatshirt with awsome logo |
| 4 | 029323 | Pants | Nice pants with awsome logo |
-------------------------------------------------------------------------
extended_article表:
-------------------------------------------------------------------------------------------------
| id | article_code | parent_article_code | name_override | description_override |
| 1 | 029320 | | T-shirt with print | |
| 2 | 029321 | 029320 | | |
| 3 | 029323 | | Awsome pants! | |
-------------------------------------------------------------------------------------------------
示例SQL查询(返回所有匹配的记录 - 不仅是子项):
SELECT article.*,
article.id,
extended_article.parent_article_code,
extended_article.impressions,
extended_article.is_base_assortment,
extended_article.is_visible,
extended_article.name_override,
extended_article.description_override,
extended_article.additional_description,
extended_article.preferred_image_file_name,
supplier.name AS supplier_name,
brand.name AS brand_name
FROM article
LEFT OUTER JOIN article_sort_order
ON article_sort_order.article_code = article.code AND category_id IS NULL
LEFT OUTER JOIN extended_article
ON extended_article.article_code = article.code
LEFT JOIN supplier
ON supplier.id = article.supplier_id
LEFT JOIN brand
ON brand.id = article.brand_id
WHERE (extended_article.is_base_assortment = 1)
AND (article.is_expired = 0)
AND (extended_article.is_visible = 1)
AND ((EXISTS
(
SELECT 1
FROM article_color_groups
WHERE article_color_groups.article_code = article.code
AND article_color_groups.color_group_id = 4
)
))
所以我的问题是: 如何有效地查询此表结构并具有仅包含父文章的结果集?
编辑:
我有一个想法是将查询部分移动到两个子查询中,只选择ID并使用UNION生成一个列表以从中选择适当的字段。这似乎有效,但可能不是最有效的解决方案?
SELECT article.*, article.id, extended_article.parent_article_code, extended_article.impressions, extended_article.is_base_assortment, extended_article.is_visible, extended_article.name_override, extended_article.description_override, extended_article.additional_description, extended_article.preferred_image_file_name, supplier.name AS supplier_name, brand.name AS brand_name
FROM article
LEFT OUTER JOIN article_sort_order ON article_sort_order.article_code = article.code AND category_id IS NULL
LEFT OUTER JOIN extended_article ON extended_article.article_code = article.code
LEFT JOIN supplier ON supplier.id = article.supplier_id
LEFT JOIN brand ON brand.id = article.brand_id
WHERE article.code IN (
SELECT article.code
FROM article
LEFT OUTER JOIN article_sort_order ON article_sort_order.article_code = article.code AND category_id IS NULL
LEFT OUTER JOIN extended_article ON extended_article.article_code = article.code
LEFT JOIN supplier ON supplier.id = article.supplier_id
LEFT JOIN brand ON brand.id = article.brand_id
WHERE (NULLIF(extended_article.parent_article_code, '') IS NULL)
AND
(extended_article.is_base_assortment = 1)
AND
(article.is_expired = 0)
AND
(extended_article.is_visible = 1)
AND
((EXISTS (SELECT 1 FROM article_color_groups WHERE article_color_groups.article_code = article.code AND article_color_groups.color_group_id = 11)))
UNION
SELECT extended_article.parent_article_code
FROM article
LEFT OUTER JOIN article_sort_order ON article_sort_order.article_code = article.code AND category_id IS NULL
LEFT OUTER JOIN extended_article ON extended_article.article_code = article.code
LEFT JOIN supplier ON supplier.id = article.supplier_id
LEFT JOIN brand ON brand.id = article.brand_id
WHERE (NULLIF(extended_article.parent_article_code, '') IS NOT NULL)
AND
(article.is_expired = 0)
AND
((EXISTS (SELECT 1 FROM article_color_groups WHERE article_color_groups.article_code = article.code AND article_color_groups.color_group_id = 11)))
)
ORDER BY -article_sort_order.sort_order DESC;