Sql server 工会不维护秩序(不稳定)

Sql server 工会不维护秩序(不稳定),sql-server,tsql,sql-server-2016,Sql Server,Tsql,Sql Server 2016,我执行下面的查询,期望第一个集合,然后是第二个集合,但顺序是完全随机的。 我期望的结果是:约翰、马克、戴夫、罗伯特、柯克 select * from ( select Name from (values ('john'),('mark'),('dave')) X(Name) union select Name from (values ('robert'),('mark'),('kirk')) X(Name) ) q 这是另一个查询,我希望它有有序(稳定

我执行下面的查询,期望第一个集合,然后是第二个集合,但顺序是完全随机的。 我期望的结果是:约翰、马克、戴夫、罗伯特、柯克

select *
from (
    select Name
    from (values ('john'),('mark'),('dave')) X(Name)
    union
    select Name
    from (values ('robert'),('mark'),('kirk')) X(Name)
) q
这是另一个查询,我希望它有有序(稳定)的结果,但我得到了相同的结果。Union All按照我的预期追加第二个集合,但应用不同的后期中断顺序

select Distinct Name
from (
    select Name
    from (values ('john'),('mark'),('dave')) X(Name)
    union all
    select Name
    from (values ('robert'),('mark'),('kirk')) X(Name)
) q

什么是有序和独立集的解决方案?

在内部
SELECT
语句中添加排序列,然后按该列排序是否合理?比如:

select Distinct Name
from (
    select SortOrder, Name
    from (values (1, 'john'),(2, 'mark'),(3, 'dave')) X(SortOrder, Name)
    union all
    select SortOrder, Name
    from (values (4, 'robert'),(2, 'mark'),(5, 'kirk')) X(SortOrder, Name)
) q
order by SortOrder ASC

保证订单的唯一方法是使用order by条款,该条款记录在BOL中:

按指定的列列表对查询的结果集排序,并(可选)将返回的行限制在指定的范围内。除非指定ORDERBY子句,否则不保证结果集中返回行的顺序

如果希望根据联合中的顺序返回行,则可以执行以下操作:

select Name
from (
    select 1 as sort1, Name
    from (values ('john'),('mark'),('dave')) X(Name)
    union
    select 2 as sort1, Name
    from (values ('robert'),('mark'),('kirk')) X(Name)
) q
order by sort1, Name

如果要先指定第一个集合,然后再指定第二个集合中不在第一个集合中的每个元素,则必须指定它。如果您想保证第一组中的内容在第二组之前列出,您还需要添加一个ORDER BY

select q.name
from (
    select Name,n
    from 
    (values ('john'),('mark'),('dave')) X(Name)
    cross join (values (1)) y(n)

    union all

    select Name,n
    from
    (
    select Name
    from (values ('robert'),('mark'),('kirk')) X(Name)

    except

    select Name 
    from
    (values ('john'),('mark'),('dave')) X(Name)

    ) Z(Name)
    Cross join (values (2)) y(n)

) q
order by q.n

如果我们使用值来选择数据,那么就不需要使用order by子句,而且我们也不必担心特定查询中可能出现的索引更改,因此您将始终保持顺序,而且我们使用union all,它只会连接结果集,而不会排序

但是,如果您使用的是table,则是的,顺序肯定会发生变化,这取决于多个因素,如表索引、返回的列、引入的新数据等。因此,如果您希望以特定方式对结果进行排序,则需要指定order BY子句

对于您的示例,您不需要像下面这样使用ORDERBY子句

select  Name
from (
    select Name
    from (values ('john'),('mark'),('dave')) X(Name)
    union all

   ( select Name
    from (values ('robert'),('mark'),('kirk')) X(Name)
    except
    select Name
    from (values ('john'),('mark'),('dave')) X(Name))

) q

添加一个订购人。没有订货人,就没有订货人guaranteed@Nick.McDermaid这并不像看上去那么简单。我不想要有序的结果。我希望得到明确的组合结果。使用
union
而不是
union all
获得明确的集合。如果您想保留两个完整的集合顺序(即第一个集合位于第二个集合的顶部),则首先需要确定是否存在重复集合,您希望从哪个集合中取出?例如,在第一个示例中,为什么标记从第二个集合中取出,而不是从第一个集合中取出?规则是什么?规则是“总是从第二个集合中提取重复项”吗?使用排名函数,并按第一个列表中的行数添加到较低的集合中……或者执行顺序的任何操作。您甚至可以考虑使用持久密钥,但我敢说,我们丢失了导致第一个订单的要求。从句将用实表替换,所以这是不被接受的答案。如果这些是固定数据,那么我可以简单地手动对它们进行清晰的排序。您甚至对名称进行排序,所以它仍然不是预期的结果。请看预期结果。第二,结果不明显。这似乎是最好的答案。
select  Name
from (
    select Name
    from (values ('john'),('mark'),('dave')) X(Name)
    union all

   ( select Name
    from (values ('robert'),('mark'),('kirk')) X(Name)
    except
    select Name
    from (values ('john'),('mark'),('dave')) X(Name))

) q