代码之家  ›  专栏  ›  技术社区  ›  Rudolf Lamprecht

如何在联合选择中保持列值的顺序?

  •  1
  • Rudolf Lamprecht  · 技术社区  · 6 年前

    我正在使用 SELECT UNION . 我需要的是 INSERT

    declare @QuestionOptionMapping table
    (
        [ID] [int] IDENTITY(1,1)
      , [QuestionOptionID] int
      , [RateCode] varchar(50)
    )
    
    insert into @QuestionOptionMapping (
        RateCode
    )
    select
       'PD0116'
    union
    select
      'PL0090'
    union
    select
      'PL0091'
    union
    select
      'DD0026'
    union
    select
      'DD0025'
    
    SELECT * FROM @QuestionOptionMapping
    

    (5 row(s) affected)
    ID          QuestionOptionID RateCode
    ----------- ---------------- --------------------------------------------------
    1           NULL             DD0025
    2           NULL             DD0026
    3           NULL             PD0116
    4           NULL             PL0090
    5           NULL             PL0091
    
    (5 row(s) affected)
    

    4 回复  |  直到 6 年前
        1
  •  0
  •   LukStorms    6 年前

    如果你不从表格中选择?
    然后您可以插入值,而不是带有联合的select。

    insert into @QuestionOptionMapping (RateCode) values
     ('PD0116')
    ,('PL0090')
    ,('PL0091')
    ,('DD0026')
    ,('DD0025')
    

    或者在您的查询中,将所有联合更改为union all。

    union和union all之间的区别在于union将删除重复的行。 而union all只是将所选结果集粘在一起。
    工会要想找到这些副本,首先必须在内部对它们进行分类。
    但是工会并不关心独特性,所以它不需要排序。

    第三种选择是简单地从一个insert语句更改为多个insert语句。 每个值插入一个。从而完全避免了联合。
    但这种反golfcoding的方法也是最冗长的。

        2
  •  5
  •   Eric Brandt    6 年前

    SQL Server将您的行存储为无序集。数据点可能是连续的,也可能不是连续的,它们可能是“顺序”,数据是在INSERT语句中指定的。

    当您查询数据时,引擎将按照优化器确定的最有效的顺序检索行。不能保证每次查询数据时订单都是相同的。

    保证结果集顺序的唯一方法是在select语句中包含一个显式的order by子句。

    请参阅此答案,以更深入地讨论为什么会出现这种情况。 Default row order in SELECT query - SQL Server 2008 vs SQL 2012

    通过对insert语句使用select/union选项,您将创建一个无序集,SQL Server将其作为一个集而不是作为一系列输入进行接收。如果需要按顺序应用标识值,请将插入分隔为离散语句。更好的是,如果行编号很重要,不要让它成为偶然。在插入时显式为行编号。

        3
  •  3
  •   Gordon Linoff    6 年前

    SQL表确实表示无序集。但是, identity insert 将按照 order by .

    由于在 union . 但是,我建议编写查询来显式地对数据排序:

    insert into @QuestionOptionMapping (RateCode)
        select ratecode
        from (values (1, 'PD0116'), 
                     (2, 'PL0090'),
                     (3, 'PL0091'),
                     (4, 'DD0026'),
                     (5, 'DD0025')
             ) v(ord, ratecode)
        order by ord;
    

    那一定要用 排序依据 对于选择:

    select qom.*
    from @QuestionOptionMapping qom
    order by id;
    

    请注意,它还使用 values() 表构造函数,这是一种非常方便的语法。

        4
  •  0
  •   paparazzo    6 年前

    你的问题是你没有按照你想的顺序把它们放进去。union仅是不同的值,它通常会对值进行排序以方便distinct。单独运行select语句,您将看到。

    如果插入时使用 values 然后保存订单:

    insert into @QuestionOptionMapping (RateCode) values
    ('PD0116'), ('PL0090'), ('PL0091'), ('DD0026'), ('DD0025')
    
    select * from @QuestionOptionMapping order by ID