将表多次连接到另一个可能具有或不具有这些值的表

发布于 2025-01-06 16:33:15 字数 961 浏览 4 评论 0原文

我有三个表:

| items
--------
id
quantity
size_attribute_value_id
color_attribute_value_id
type_attribute_value_id

| attribute_values (instance of an attribute, like red, xsmall)
--------
id
attribute_id
name

| attributes (attribute category, like color, size)
id
name 

三个属性(大小、颜色、类型)的任意组合都可以生成有效的项目。因此,我希望能够查询这三个属性的所有组合,同时还包括项目表中现有的项目。我的想法是我想要一个包含所有现有项目和所有可能的有效未来项目的结果集。例如,即使 items 表完全空白,我仍然应该得到数量为 0 的不存在但有效的项目的结果。

有效的 attribute_ids 为 1、2、4。

我尝试了以下右连接作为开始:

SELECT i.*, av1.*, av2.*, av3.*
FROM items i 
RIGHT OUTER JOIN attribute_values av1 ON av1.attribute_id = 2 AND av1.id = i.size_attribute_value_id
RIGHT OUTER JOIN attribute_values av2 ON av2.attribute_id = 4 AND av2.id = i.color_attribute_value_id
RIGHT OUTER JOIN attribute_values av3 ON av3.attribute_id = 1 AND av3.id = i.type_attribute_value_id;

但它只返回大约 200 行,而实际应该超过 1000 行。

任何帮助,即使只是正确方向的一点,我们都会表示赞赏。

I have three tables:

| items
--------
id
quantity
size_attribute_value_id
color_attribute_value_id
type_attribute_value_id

| attribute_values (instance of an attribute, like red, xsmall)
--------
id
attribute_id
name

| attributes (attribute category, like color, size)
id
name 

Any combination of the three attributes (size, color, type) can make a valid item. Therefore, I want to be able to query for all combinations of the three attributes, while also including already existing items from the items table. The idea being I want a result set of all existing items and all possible valid future items. For example, even if the items table is completely blank, I should still get results of non-existent but valid items with quantities of 0.

Valid attribute_ids are 1, 2, 4.

I've tried the following right join as a start:

SELECT i.*, av1.*, av2.*, av3.*
FROM items i 
RIGHT OUTER JOIN attribute_values av1 ON av1.attribute_id = 2 AND av1.id = i.size_attribute_value_id
RIGHT OUTER JOIN attribute_values av2 ON av2.attribute_id = 4 AND av2.id = i.color_attribute_value_id
RIGHT OUTER JOIN attribute_values av3 ON av3.attribute_id = 1 AND av3.id = i.type_attribute_value_id;

But it's only returning about 200 rows, when it should be more over 1000.

Any help, even if just a point in the right direction, is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我三岁 2025-01-13 16:33:15
SELECT a1.name as `type`, a2.name as `size`, a4.name as `color`, SUM(COALESCE( i.quantity , 0 ) ) as quantity
FROM (attribute_values a1, attribute_values a2, attribute_values a4)
LEFT JOIN items i
ON i.type_attribute_value_id = a1.id
AND i.size_attribute_value_id = a2.id
AND i.color_attribute_value_id = a4.id
WHERE a1.attribute_id = 1 AND a2.attribute_id = 2 AND a4.attribute_id = 4
GROUP BY a1.name, a2.name, a4.name

这假设您的项目表中除了类型、尺寸和颜色之外还有很多其他属性,并且可能有更多列,如果没有,最好将属性放在单独的表中,例如类型、颜色和尺寸,当数据库变大时,这将更容易查询,并通过适当的索引为您带来显着的性能改进。

SELECT a1.name as `type`, a2.name as `size`, a4.name as `color`, SUM(COALESCE( i.quantity , 0 ) ) as quantity
FROM (attribute_values a1, attribute_values a2, attribute_values a4)
LEFT JOIN items i
ON i.type_attribute_value_id = a1.id
AND i.size_attribute_value_id = a2.id
AND i.color_attribute_value_id = a4.id
WHERE a1.attribute_id = 1 AND a2.attribute_id = 2 AND a4.attribute_id = 4
GROUP BY a1.name, a2.name, a4.name

This assumes you have also a lot of other attributes other than type, size and color and possibly more columns in your items table, if you don't it would be much better to put attributes in separate tables, like types, colors and sizes, which would be easier to query and give you noticeable performance improvement with proper indexing when your database grows big.

英雄似剑 2025-01-13 16:33:15

我认为这应该可以做到 -

SELECT *
FROM (SELECT * FROM attribute_values WHERE attribute_id = 4) AS `color`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 2) AS `size`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 1) AS `type`
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`

我已经重写了这个查询以避免派生表。它应该表现得更好。

SELECT color.name, size.name, type.name, IFNULL(items.quantity, 0) AS quantity
FROM attribute_values AS `color`
INNER JOIN attribute_values AS `size`
    ON size.attribute_id = 2
INNER JOIN attribute_values AS `type`
    ON type.attribute_id = 1
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`
WHERE color.attribute_id = 4;

I think this should do it -

SELECT *
FROM (SELECT * FROM attribute_values WHERE attribute_id = 4) AS `color`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 2) AS `size`
INNER JOIN (SELECT * FROM attribute_values WHERE attribute_id = 1) AS `type`
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`

I have rewritten this query to avoid the derived tables. It should perform better.

SELECT color.name, size.name, type.name, IFNULL(items.quantity, 0) AS quantity
FROM attribute_values AS `color`
INNER JOIN attribute_values AS `size`
    ON size.attribute_id = 2
INNER JOIN attribute_values AS `type`
    ON type.attribute_id = 1
LEFT JOIN items
    ON `color`.`id` = `items`.`color_attribute_value_id`
    AND `size`.`id` = `items`.`size_attribute_value_id`
    AND `type`.`id` = `items`.`type_attribute_value_id`
WHERE color.attribute_id = 4;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文