简体   繁体   中英

SQL Query multiple where clause prioritize

I have following SQL query

SELECT * FROM train_stop where code='ABC' OR code='XYZ' OR code='DEF' group by number order by departs

Now since i am using Group By so as to take only one row with specific number. But i want to prioritize the result. It means if my table has code='ABC' and code='XYZ' , then the result must select ABC row and not 'XYZ' because ABC has come first in where clause. Similarly if table has XYZ and DEF for same number, XYZ must come up in result and not DEF . Till now my experiments led me that its hows on random basis. I would be helpful if you could guide me to achieve this and proper indexing strategy for this case. Thanks.

The create statement is as follows-

Create Statement is `CREATE TABLE `train_stop` (
  `number` varchar(1000) NOT NULL,
  `stop_number` int(11) NOT NULL,
  `code` varchar(1000) NOT NULL,
  `station name` varchar(1000) NOT NULL,
  `arrives` time NOT NULL,
  `departs` time NOT NULL,
  `halt` varchar(1000) NOT NULL,
  `pf` varchar(1000) NOT NULL,
  `day` int(11) NOT NULL,
  `km` varchar(1000) NOT NULL,
  `speed` varchar(1000) NOT NULL,
  `elev` varchar(1000) NOT NULL,
  `zone` varchar(1000) NOT NULL,
  `address` varchar(1000) NOT NULL,
  `active` int(11) DEFAULT '1',
  KEY `index_1` (`number`(767),`code`(767)),
  KEY `PIndex` (`number`(767),`stop_number`),
  KEY `three_columns_idx` (`code`(767),`active`,`departs`),
  KEY `two_columns_idx` (`code`(767),`active`),
  KEY `two_columns_group_idx` (`number`(767),`departs`),
  KEY `one_columns_group_idx` (`departs`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1`

Group by is the wrong way to do this. This will do it. You would need to change the order by portion to match your where clause ordering whenever you change the codes to check against.

select * from (
  select if(@prev = number, @rank := @rank + 1, @rank := 1 and @prev := number) rank, 
         train_stop.*
    from train_stop, (select @prev := 0, @rank := 1) q  
  where code = 'abc' 
    or code = 'xyz' 
    or code = 'def' 
  order by number asc, code='abc' desc, code='xyz' desc, code='abc' desc
) q where rank = 1;

Demo here: http://sqlfiddle.com/#!9/ccc4d/7

This query assigns a rank per ordered group, and then selects just the top ranked value out of each group. Would probably break if you have a station number 0

Try this.

SELECT * 
FROM train_stop 
where code='ABC' 
 OR ( code != 'ABC'
  and code = 'XYZ' )
 OR ( code != 'ABC'
  and code != 'XYZ'
  and code='DEF' )
group by number
order by departs
SELECT * FROM (SELECT * FROM train_stop where code='ABC' OR code='XYZ' OR 
code='DEF' order by departs ASC) as t group by t.number 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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