如何在mysql中为某些选择一行(或在选择中赋予优先级?

问题描述 投票:2回答:4

需要您的帮助人员来构成查询。

示例。公司-租车

桌子-汽车

ID  NAME       STATUS
1   Mercedes   Showroom
2   Mercedes   On-Road

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

  1. 如果梅赛德斯陈列室有售,则仅获取该行。 (即上例中的第1行)

  2. 但是,如果陈列室中没有一辆梅赛德斯奔驰,请提取其中任何一排。 (即第1行或第2行)-(这只是说所有的奔驰车都在路上)

在这里使用独特的方法无济于事,因为在选择语句中也获取了ID

谢谢!

sql mysql ranking rank
4个回答
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和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;

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

3
投票

您可能想使用FIND_IN_SET()功能来做到这一点。

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

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

EDIT删除了UNION上的ALL,因为我们始终只需要不同的行。

© www.soinside.com 2019 - 2024. All rights reserved.