简体   繁体   English

如何按联接表的行(而非列)中的值对mysql查询结果排序?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM