MySQL从多个选项加入以选择一个值

时间:2009-12-10 07:01:21

标签: sql mysql select join

我正在整理一个很好的小数据库,用于为选项添加值,所有这些都是通过地图(Has和Belongs to Many)表设置的,因为很多选项都指向一个值。

所以我试图在值表中指定3个option.ids和一个id - 四个整数指向单个值。三张桌子。我遇到了语句的WHERE部分的问题,因为如果多个值共享一个选项,则会有很多结果。我只需要一个结果。

SELECT value.id, value.name FROM value
 LEFT JOIN (option_map_value, option_table)
 ON (value.id = option_map_value.value_id AND option_map_value.option_table_id = option_table.id)
 WHERE option_table.id IN (5, 2, 3) AND value.y_axis_id = 16;

语句的问题似乎是WHERE子句上的IN。如果IN()部分中的一个数字不同,那么会有多个结果 - 这是不好的。

我尝试了DISTINCT,如果有一个结果,它会再次起作用,但如果有很多则会返回很多。我们最接近的是添加一个计数 - 返回顶部最多选项的值。

有没有办法让WHERE更具体。我无法将其分解为option_table.id = 5 AND option_table.id = 2 - 因为那个失败了。但WHERE子句可以更具体吗?

也许是我迂腐,但我希望能够只返回一个结果,而不是结果......任何想法?

1 个答案:

答案 0 :(得分:6)

  

语句的问题似乎是WHERE子句上的IN。如果IN()部分中的一个数字不同,那么有多个结果 - 这是不好的。我尝试过DISTINCT,如果有一个结果,它会再次起作用,但如果有很多则会返回很多。我们最接近的是添加一个计数 - 返回顶部最多选项的值。

考虑到DISTINCT

,你非常接近
    SELECT v.id, 
           v.name 
      FROM VALUE v
 LEFT JOIN OPTION_MAP_VALUE omv ON omv.value_id = v.id
 LEFT JOIN OPTION_TABLE ot ON ot.id = omv.option_table_id
     WHERE ot.id IN (5, 2, 3) 
       AND v.y_axis_id = 16
  GROUP BY v.id, v.name
    HAVING COUNT(*) = 3

您走在正确的轨道上,但需要使用GROUP BY代替才能使用HAVING子句来计算DISTINCT值列表。

警告:
GROUP BY/HAVING COUNT版本的查询取决于您的数据模型,该数据模型具有为所涉及的两列(value_idoption_table_id)定义的复合键,唯一键或主键。如果没有,数据库将不会停止添加重复项。如果数据中存在重复行,则此版本可以返回误报,因为value_id可能与option_table_id 5有3个关联 - 这将满足HAVING COUNT(*) = 3

使用JOIN:

一种更安全但更具参与性的方法是加入可以有多个选项的表格,就像你有标准一样:

  SELECT v.id, 
         v.name 
    FROM VALUE v
    JOIN OPTION_MAP_VALUE omv ON omv.value_id = v.id
    JOIN OPTION_TABLE ot5 ON ot5.id = omv.option_table_id
                         AND ot5.id = 5
    JOIN OPTION_TABLE ot2 ON ot2.id = omv.option_table_id
                         AND ot2.id = 2
    JOIN OPTION_TABLE ot3 ON ot3.id = omv.option_table_id
                         AND ot3.id = 3
   WHERE v.y_axis_id = 16
GROUP BY v.id, v.name