简体   繁体   中英

How can I write this SQL query where I want to extract a subset based on sorting on multiple values in the simplest way?

I have a table with around 40 columns. Of these I want to first extract all rows with min(col_a) . Then in this subset I want to get all rows that correspond to min(col_b) and lastly from this subset I want the resulting rows with an arbitrary, but distinct col_c value and sorted on col_d . Below is how I did it and it seemed to work, until I figured that columns were text type, so it didn't sort correctly. Then I cast the columns to integer, but distinct wouldn't allow that.

SELECT * 
FROM @this 
WHERE (col_c, col_a, col_b) = (
    SELECT DISTINCT col_c, col_a, col_b 
    FROM @this 
    WHERE col_whatever='false' 
    ORDER BY col_a ASC, col_b ASC LIMIT 1) 
ORDER BY col_d ASC;

Any help would be highly appreciated. Here's an example of how I want it to work:

col_a | col_b | col_c | col_d | ...
  1   |   2   |   5   |   3   |  
  1   |   2   |   5   |   2   |
  2   |   1   |   2   |   1   | 
  4   |   3   |   3   |   1   |
  1   |   4   |   2   |   3   | 
  2   |   3   |   5   |   2   |

=> Rows: [1,2,5,2] [1,2,5,3]

When those are processed I would like rows to be: [1,4,2,3] Next time: [2,1,2,1]

Note col_c doesn't have to be ordered, just the same value for all the resulting rows.

UPDATE: This worked. Don't know if I have to cast every time I use a column, but it works.

SELECT * FROM @this 
WHERE (col_c,col_a::INTEGER,col_b::INTEGER) = (SELECT 
    col_c,col_a::INTEGER,col_b::INTEGER 
    FROM @this 
    WHERE col_whatever='false' 
    ORDER BY col_a::INTEGER ASC, col_b::INTEGER ASC LIMIT 1)
ORDER BY col_d::INTEGER ASC;

Just drop the DISTINCT, the LIMIT 1 ensures you'll get only one value for col_c anyway. If you need to sort col_d as an integer, cast it accordingly in the outer ORDER BY clause.

SELECT * 
FROM @this 
WHERE (col_c, col_a, col_b) = (
    SELECT col_c, col_a, col_b 
    FROM @this 
    WHERE col_whatever='false' 
    ORDER BY col_a::integer ASC, col_b::integer ASC LIMIT 1) 
ORDER BY col_d::integer ASC;

Hope this helps.

EDIT: you'll need to cast col_a and col_b as integer as well

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