Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use order by with specific value

Tags:

sql

mysql

CREATE TABLE Countries(location varchar(255), country varchar(255))

INSERT INTO Countries(location, country)
               VALUES('Arkansas', 'US'),
                      ('Newyork', 'US'),
                      ('New Jersey', 'US'),
                      ('Tokyo', 'JP'),
                      ('Yokohama', 'JP'),
                      ('Chennai', 'IN'),
                      ('Delhi', 'IN'),
                      ('Sydney', 'AU'),
                      ('Melbourne', 'AU');

I need a query for the following output

 Location     |         Country
--------------------------------
  Arkansas                US
  Tokyo                   JP
  Chennai                 IN
  Sydney                  AU
  Newyork                 US
  Yokohama                JP
  Delhi                   IN
  Melbourne               AU
  New Jersey              US 
like image 414
user1187 Avatar asked Nov 22 '12 09:11

user1187


People also ask

How do you use condition in ORDER BY clause?

SELECT column-list FROM table_name [WHERE condition] [ORDER BY column1, column2, .. columnN] [ASC | DESC]; You can use more than one column in the ORDER BY clause. Make sure whatever column you are using to sort that column should be in the column-list.

How do I sort by a specific column in SQL?

The ORDER BY statement in SQL is used to sort the fetched data in either ascending or descending according to one or more columns. By default ORDER BY sorts the data in ascending order. We can use the keyword DESC to sort the data in descending order and the keyword ASC to sort in ascending order.

How do you use ORDER BY clause with SQL statement what is its use?

The SQL ORDER BY Keyword The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.


2 Answers

You need to give each location a rank based on its relative order within its own country. You can use variable to create a makeshift rownumber function in MySQL:

SELECT  Country,
        Location,
        @r:= CASE WHEN Country = @c THEN @r + 1 ELSE 1 END AS RN,
        @c:= Country AS C2
FROM    Countries,
        (SELECT @r:= 1) r,
        (SELECT @c:= '') c
ORDER BY Country, Location;

This will output

COUNTRY     LOCATION    RN  C2
AU          Melbourne   1   AU
AU          Sydney      2   AU
IN          Chennai     1   IN
IN          Delhi       2   IN
JP          Tokyo       1   JP
JP          Yokohama    2   JP
US          Arkansas    1   US
US          New Jersey  2   US
US          Newyork     3   US

Then you can order this by RN, and Country to get the order you want

SELECT  Location, Country
FROM    (   SELECT  Country,
                    Location,
                    @r:= CASE WHEN Country = @c THEN @r + 1 ELSE 1 END AS RN,
                    @c:= Country AS C2
            FROM    Countries,
                    (SELECT @r:= 1) r,
                    (SELECT @c:= '') c
            ORDER BY Country, Location
        ) c
ORDER BY rn, Country DESC;

Example on SQL Fiddle

EDIT

Since you are getting collation errors, but haven't specified what the collation errors are the only way I can hope to correct this is use explicit collation for everything:

SELECT  Location, Country
FROM    (   SELECT  Country COLLATE utf8_general_ci AS Country,
                    Location COLLATE utf8_general_ci AS Location,
                    @r:= CASE WHEN Country = @c THEN @r + 1 ELSE 1 END AS RN,
                    @c:= Country COLLATE utf8_general_ci AS C2
            FROM    Countries,
                    (SELECT @r:= 1) r,
                    (SELECT @c:= '' COLLATE utf8_general_ci) c
            ORDER BY Country, Location
        ) c
ORDER BY rn, Country DESC

SQL FIDDLE

like image 69
GarethD Avatar answered Oct 16 '22 03:10

GarethD


You can't order your table the way you want without having an id. You could create your table this way:

CREATE TABLE Countries(
  id INT NOT NULL AUTO_INCREMENT,
  location varchar(255),
  country varchar(255),
  PRIMARY KEY(ID))

ant then you can insert your data:

INSERT INTO Countries(location, country)
           VALUES('Arkansas', 'US'),
           ...

Ant then I would write the query using just standard SQL as this:

SELECT *
FROM Countries c1
ORDER BY (select count(*)
          from countries c2
          where c1.country=c2.country
          and c1.id>c2.id), id

this query might not be fast, but it will work. But without using an id there's no way to answer your question. SQL tables have no default order, so if there's no id there's no way to tell that, for example, Sydney comes before Melbourne, even if it was inserted first.

like image 39
fthiella Avatar answered Oct 16 '22 04:10

fthiella