如何在mysql中选择某一行(或在选择中给出优先选择)?

时间:2010-06-20 15:14:03

标签: sql mysql ranking rank

需要你的帮助人员来形成一个查询。

实施例。 公司 - 租车

表 - 汽车

ID  NAME       STATUS
1   Mercedes   Showroom
2   Mercedes   On-Road

现在,如何从此表中只选择一个满足以下条件的条目?

  1. 如果Mercedes在Showroom中可用,则只获取该行。 (即上例中的第1行)

  2. 但如果陈列室中没有梅赛德斯,那么就可以获取任何一行。 (即第1行或第2行) - (这只是说所有奔驰车都在路上)

  3. 使用distinct在这里没有帮助,因为ID也在select语句中被提取

    谢谢!

4 个答案:

答案 0 :(得分:3)

以下是解决该问题的常用方法:

SELECT *,
CASE STATUS
WHEN 'Showroom' THEN 0
ELSE 1
END AS InShowRoom
FROM Cars
WHERE NAME = 'Mercedes'
ORDER BY InShowRoom
LIMIT 1

以下是如何获得所有汽车,这也显示了另一种解决问题的方法:

SELECT ID, NAME, IFNULL(c2.STATUS, c1.STATUS)
FROM Cars c1
LEFT OUTER JOIN Cars c2
ON c2.NAME = c1.NAME AND c2.STATUS = 'Showroom'
GROUP BY NAME
ORDER BY NAME

答案 1 :(得分:2)

您可能希望使用FIND_IN_SET()函数来执行此操作。

SELECT *
FROM Cars
WHERE NAME = 'Mercedes'
ORDER BY FIND_IN_SET(`STATUS`,'Showroom') DESC
LIMIT 1

如果您有其他状态的首选顺序,只需将它们添加到第二个参数。

ORDER BY FIND_IN_SET(`STATUS`,'On-Road,Showroom' ) DESC

要获取所有汽车的“最佳”状态,您只需执行此操作:

SELECT *
FROM Cars
GROUP BY NAME
ORDER BY FIND_IN_SET(`STATUS`,'Showroom') DESC

答案 2 :(得分:1)

SELECT * FROM cars 
  WHERE name = 'Mercedes' 
  AND status = 'Showroom' 
UNION SELECT * FROM cars 
  WHERE name = 'Mercedes' 
LIMIT 1;

编辑删除了UNION上的ALL,因为我们只想要不同的行。

答案 3 :(得分:0)

MySQL没有排名/分析/窗口函数,但您可以使用变量来模拟ROW_NUMBER功能(当您看到“ - ”时,它是评论):

SELECT x.id, x.name, x.status
  FROM (SELECT t.id,
               t.name,
               t.status,
               CASE 
                 WHEN @car_name != t.name THEN @rownum := 1 -- reset on diff name
                 ELSE @rownum := @rownum + 1 
               END AS rank,
               @car_name := t.name -- necessary to set @car_name for the comparison
          FROM CARS t 
          JOIN (SELECT @rownum := NULL, @car_name := '') r
      ORDER BY t.name, t.status DESC) x  --ORDER BY is necessary for rank value
 WHERE x.rank = 1

按状态排序DESC意味着“陈列室”将位于列表的顶部,因此它将被排名为1.如果汽车名称没有“陈列室”状态,则排名为1的行将无论“陈列室”之后出现什么状态。 WHERE子句只返回表中每辆汽车的第一行。

状态是基于文本的数据类型告诉我您的数据未规范化 - 我可以使用“Showroom”,“SHOWroom”和“showROOM”添加记录。它们是有效的,但你正在寻找使用像LOWER& amp;当你对计数,求和等进行分组时,UPPER使用函数也会使列上的索引无用......你会考虑制作一个CAR_STATUS_TYPE_CODE表,并使用外键关系来确保错误数据无法进入您的表格:

DROP TABLE IF EXISTS `example`.`car_status_type_code`;
CREATE TABLE  `example`.`car_status_type_code` (
  `car_status_type_code_id` int(10) unsigned NOT NULL auto_increment,
  `description` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`car_status_type_code_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;