从具有给定条件的一个表中选择多个不同类型的行,如果未找到则选择下一个可能的行

时间:2012-10-04 11:35:15

标签: mysql select join settings

我有一种设置表,其中包括类型,值,公司,组等列。从该表中我只需要选择每种不同类型的一行,具体取决于我的用户信息是否与其他列匹配。

示例我在公司1和组1中,我的设置表包含以下行:

+--+-----+-------+---------+-------+
|id|type | value | company | group |
+--+-----+-------+---------+-------+
|1 |1    | 50    | 1       | 1     |
|2 |1    | 70    | NULL    | NULL  |
|3 |2    | 1     | NULL    | NULL  |
|4 |2    | 99    | 1       | 1     |
|5 |2    | 999   | NULL    | 1     |
|6 |3    | 500   | NULL    | NULL  |
+--+-----+-------+---------+-------+

如果有公司或组的设置使用它,否则使用默认行(公司和组为NULL)。公司和集团还有更多专栏。

从该表中我需要选择id:s 1,4和6,因为它们是我在这种情况下需要的设置。 Id 1和id 4与我的用户信息匹配,id 5也匹配,但id 4完全匹配。 Id 6匹配,因为没有更接近类型3的设置。

可能有数百家公司和团体,因此我不想创建PHP算法来获得正确的设置值。这将是灾难性的。

我尝试选择行并使用公司DESC对它们进行排序,但是在分组类型时它不会起作用。我还尝试加入公司IS not NULL的max(公司),但我陷入困境,现在正试图寻求帮助。

如果有人可以帮我解决这个问题,我将不胜感激!

1 个答案:

答案 0 :(得分:2)

SELECT * FROM my_table WHERE id IN (
  SELECT (
    SELECT   b.id
    FROM     my_table b
    WHERE    b.type = a.type
         AND IFNULL(b.company = 1, TRUE)
         AND IFNULL(b.group   = 1, TRUE)
    ORDER BY b.company DESC, b.group DESC
    LIMIT    1
  ) FROM (
    SELECT DISTINCT type FROM my_table
  ) a
)

sqlfiddle上查看。


重写JOIN,这应该会带来更好的效果:

SELECT my_table.*
FROM   my_table
JOIN (
  SELECT DISTINCT type FROM my_table
) a ON my_table.id = (
  SELECT   b.id
  FROM     my_table b
  WHERE    b.type = a.type
       AND IFNULL(b.company = 1, TRUE)
       AND IFNULL(b.group   = 1, TRUE)
  ORDER BY b.company DESC, b.group DESC
  LIMIT    1
)

sqlfiddle上查看。