简体   繁体   English

用ORDER BY连接两个SQL查询

[英]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. 我在PHP中使用上述查询,根据优先级对列进行排序,优先级设置为1-6,其余记录设置为优先级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 但是,因为alt_names列共享item_name的优先级,所以它像这样出现

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. 我不想不必两个单独的查询,然后使用php将它们组合在一起。

EDIT: My php code that deals with the delimiting 编辑:我的PHP代码处理定界

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. 使用这样的表,构造UNION查询以获取所需的结果很简单。 Here, we assign a default priority of 1000 to all alternative names: 在这里,我们为所有替代名称分配默认优先级1000:

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: 就像我在评论中说的那样,我不是Php专家(我是C#+ SQL),但我知道逻辑,我认为您需要这样的东西:

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. 因为您的示例显示10002 1000排序,所以我假设varchar列是priority

Casting it to int for ordering will give a better result: 将其强制转换为int以进行排序将获得更好的结果:

order by cast(priority as int), item_name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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