[英]How do I order mysql query results by values from a joined table's rows (not columns)?
I have a table items
and a table parameters
. 我有一个表items
和一个表parameters
。 A join table of item_parameters
stores the value for each possible parameter for an item, instead of having a separate column for each parameter. item_parameters
表存储项的每个可能参数的值,而不是为每个参数具有单独的列。
For example (simplified): 例如(简体):
parameters: items:
id: 1, name: color id: 1, name: bike
id: 2, name: size id: 2, name: phone
id: 3, name: weight id: 3, name: shoe
item_parameters:
id: 1, item_id: 1, parameter_id: 1, value: "blue"
id: 2, item_id: 1, parameter_id: 2, value: "large"
id: 3, item_id: 1, parameter_id: 3, value: "heavy"
id: 4, item_id: 2, parameter_id: 1, value: "black"
id: 5, item_id: 2, parameter_id: 2, value: "medium"
id: 6, item_id: 2, parameter_id: 3, value: "medium"
id: 7, item_id: 3, parameter_id: 1, value: "white"
id: 8, item_id: 3, parameter_id: 2, value: "small"
id: 9, item_id: 3, parameter_id: 3, value: "light"
How can I search for items (applying a filter for specific parameters) and order the results based on the value
of a particular parameter
for the items
? 如何搜索项目(对特定参数应用过滤器)并根据items
的特定parameter
value
对结果进行排序?
I know how to apply the filter part, using a where clause with item_parameters.parameter_id = ? AND item_parameters.value = ?
我知道如何使用带有item_parameters.parameter_id = ? AND item_parameters.value = ?
的where子句来应用过滤器部分item_parameters.parameter_id = ? AND item_parameters.value = ?
item_parameters.parameter_id = ? AND item_parameters.value = ?
But for the ordering part, simply adding ORDER BY item_parameters.value desc
doesn't seem to be enough to order by only those item_parameters.value
where item_parameters.parameter_id = ?
但是对于订购部分,仅添加ORDER BY item_parameters.value desc
似乎不足以仅按那些item_parameters.value
进行订购, where item_parameters.parameter_id = ?
. 。
In my results of items, I want all item_parameters
for that item
including the parameters
that weren't used in the order by clause. 在项目结果中,我希望该item
所有item_parameters
都包括order by子句中未使用的parameters
。
This query is still a work in progress because I don't yet have it returning all item_parameters
for each item
: 该查询仍在进行中,因为我还没有返回每个item
所有item_parameters
:
SELECT DISTINCT
`items`.name,
`parameters`.name,
`item_parameters`.value
FROM `items`
LEFT OUTER JOIN `item_parameters` ON `item_parameters`.`item_id` = `items`.`id`
LEFT OUTER JOIN `parameters` ON `item_parameters`.`parameter_id` = `parameters`.`id`
WHERE (item_parameters.parameter_id = 3 AND item_parameters.value = 'light')
ORDER BY item_parameters.value LIMIT 10000;
In addition currently not returning all item_parameters, the relevant missing piece above for this post is that the order logic (pseudocode) needs to be ORDER BY items_parameters.value where item_parameters.parameter_id = 1
除了当前不返回所有item_parameters之外,此帖子上面的相关遗漏之处在于,订单逻辑(伪代码)需要为ORDER BY items_parameters.value where item_parameters.parameter_id = 1
Here is an example of desired results, assumes from a larger example data set than the provided example above: 这是预期结果的示例,并假设比上面提供的示例更大的示例数据集:
item name color size weight
cup brown small light
shirt green medium light
candy pink large light
chair tan medium light
paper white large light
Notice that the results are all filtered on parameter 3 (weight) = light and ordered on parameter 1 (color). 请注意,所有结果均按参数3(权重)=浅色过滤,并按参数1(颜色)排序。
Thanks for any guidance on this. 感谢您对此的任何指导。
I'm not sure it's best for performance but here's how I would logically construct the query. 我不确定这对性能最好,但是这就是我逻辑上构造查询的方式。
First SELECT all the items and their parameters: 首先选择所有项目及其参数:
SELECT i.name, p.name, ip.value
FROM items i
JOIN item_parameters ip
ON ip.item_id = i.id
JOIN parameters p
ON p.id = ip.parameter_id
Then make sure you only have items that have the correct value for a particular param: 然后,确保您只有对于特定参数具有正确值的项目:
JOIN item_parameters ip3
ON ip3.parameter_id = 3
AND ip3.item_id = i.id
AND ip3.value = 'light'
Then include the param that you are ordering by: 然后包括您要订购的参数:
JOIN item_parameters ip1
ON ip1.parameter_id = 1
AND ip1.item_id = i.id
Then add the ORDER BY: 然后添加ORDER BY:
ORDER BY ip1.value DESC, i.id, p.id
If you are ordering by a parameter that may not be present, you'll have to LEFT JOIN to that one and choose where to put the resultant NULL values. 如果要按可能不存在的参数进行排序,则必须向左LEFT JOIN并选择将生成的NULL值放在何处。
This also will NOT pivot the table as shown in your example results, but will keep the items grouped together nicely. 这也不会像您的示例结果所示那样旋转表,但是会很好地将项目分组在一起。
If you wish to have the pivoted table, you'll probably have to join all the parameters separately, similar to 1 and 3 above. 如果希望使用透视表,则可能必须分别连接所有参数,类似于上面的1和3。 You can either do this manually or by dynamically building the query from a list of expected/required parameters. 您可以手动执行此操作,也可以通过从期望/必需参数列表中动态构建查询来执行此操作。
UPDATE 更新
For the pivoted results shown, with a bit of hard coding: 对于所示的关键结果,进行一些硬编码:
SELECT i.name, color.value color, size.value size, weight.value weight
FROM items i
JOIN item_parameters color
ON color.parameter_id = 1
AND color.item_id = i.id
JOIN item_parameters size
ON size.parameter_id = 2
AND size.item_id = i.id
JOIN item_parameters weight
ON weight.parameter_id = 3
AND weight.item_id = i.id
WHERE weight.value = 'light'
ORDER BY color.value DESC
You could join on the parameters table to get the names too just in case they change, but this gives you an outline. 您可以加入参数表以获取名称,以防万一它们发生更改,但这为您提供了一个轮廓。
The downside of this approach is that the query will have to be updated every time you add a new parameter. 这种方法的缺点是,每次添加新参数时都必须更新查询。
Personally, I prefer the group style method, the pivot table can be generated using application code. 我个人更喜欢使用组样式方法,可以使用应用程序代码生成数据透视表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.