简体   繁体   中英

Join two sql queries with ORDER BY

SELECT item_name, alt_names 
FROM antidepressants 
WHERE status = 'verified' 
ORDER BY priority, item_name

I'm using the above query within PHP to order the columns based on a priority, priority is set 1-6 and the rest of the records are set to priority 1000.

This is an example of the table

item_name   alt_name    priority
a           null        1000
b           null        1000
c           null        1000
d           null        1000
e           null        1000
x           f,g         1
y           h           2
z           null        3

What I'm hoping for is the following

x
y
z
a
b
c
d
e
f
g
h

However because alt_names column shares the priority of item_name it is coming up like this

x
f
g
y
h
z
a
b
c
d
e

It seems like I need a way to do two queries and then combine then within one query. I'd prefer not to have to two separate queries and then use php to combine them.

EDIT: My php code that deals with the delimiting

function populateAutocomplete()
{
    $query       = "SELECT item_name, alt_names FROM antidepressants WHERE status = 'verified' ORDER BY priority, item_name";
    $result_conn = conn($query);

    $autocomplete = array();
    if ($result_conn[0]->num_rows > 0) {
        while ($row = $result_conn[0]->fetch_assoc()) {
            $altnames = explode(",", $row['alt_names']);
            //var_dump($altnames);
            array_push($autocomplete, $row['item_name']);
            $autocomplete = array_merge($autocomplete, $altnames);
            }
        } 
    else {
        echo "0 results";
    }
    $result_conn[1]->close();
    foreach($autocomplete as &$val) {
        $val = trim($val);
    }
    $autocomplete = array_filter($autocomplete);
    $implode  = implode(",", $autocomplete);
    echo $implode;
}

Unfortunately, what you're asking is more trouble than fixing your table definition. Any time you think a comma delimited field is a good idea, remind yourself that it really isn't, and that you should normalise your tables.

Instead of a list of alternative names in the table, what you should have is a second table, purely for alternative names. For example:

create table alternative_names (
       item_name varchar(25),
       alt_name varchar(25)
);

With such a table it is a simple matter to construct a UNION query to get the results you want. Here, we assign a default priority of 1000 to all alternative names:

select * from (
  SELECT item_name, priority
    from antidepressants
  UNION ALL
  SELECT alt_name, 1000
    from alternative_names
  ) q
order by priority asc, item_name asc;

There is a demo of this here

Given that there is no way beforehand to know how many alternative names you have in your single table, there is no single, simple query that will do what you want.

Like I say in my comment I'm no Php expert (I'm more C# + SQL) but I know logic and I think something like this is what you need:

function populateAutocomplete()
{
    $query       = "SELECT item_name, alt_names FROM antidepressants WHERE status = 'verified' ORDER BY priority, item_name";
    $result_conn = conn($query);

    $autocomplete = array();
    if ($result_conn[0]->num_rows > 0) {
        while ($row = $result_conn[0]->fetch_assoc()) { //While to add item_name to array
            array_push($autocomplete, $row['item_name']);
            }
            $row = 0;
        while ($row = $result_conn[0]->fetch_assoc()) { //while to add alt_names to end of array
            $altnames = explode(",", $row['alt_names']);
            //var_dump($altnames);
            $autocomplete = array_merge($autocomplete, $altnames);
        }

        } 

    else {
        echo "0 results";
    }
    $result_conn[1]->close();
    foreach($autocomplete as &$val) {
        $val = trim($val);
    }
    $autocomplete = array_filter($autocomplete);
    $implode  = implode(",", $autocomplete);
    echo $implode;

Because your example shows 1000 sorted above 2 , I assume priority is a varchar column.

Casting it to int for ordering will give a better result:

order by cast(priority as int), item_name

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