【问题标题】:SQL - Insert multiple records from selectSQL - 从选择中插入多条记录
【发布时间】:2016-10-01 21:10:22
【问题描述】:

我已经搜索了一整天,但找不到答案:

我在 SQL Server 上有一个表:

dbo.程序

带字段:

  • Program.id...PK 自动增量
  • Program.user...varchar
  • Program.program...varchar
  • Program.installed...布尔值
  • Program.department...varchar
  • Program.wheninstalled...日期

现在,我想为每个不同的用户插入一条新记录,并从他的最新(Program.wheninstalled)记录中复制部门,并为每个用户提供相同的其他值:

  • Program.user...每个唯一的用户
  • Program.program...MyMostAwesomeProgram
  • Program.installed...false
  • Program.department...program.user 中唯一用户的所有记录中具有最新 program.wheninstalled 字段的记录的部门
  • Program.wheninstalled...null

我知道如何以丑陋的方式做到这一点:

  1. 为该记录中的每个用户及其部门选择最新记录
  2. 从 1) 中提取值并插入到 (field1, field2...fieldX) 值 (1records_value1, 1records_value2...1records_valueX), (2records_value1, 2records_value2...2records_valueX), ... (Nrecords_value1, Nrecords_value2...Nrecords_valueX)

但我想知道如何以更好的方式做到这一点。哦,我不能使用一些适当的 HR 数据库来让我的生活更轻松,所以这就是我现在必须使用的。

【问题讨论】:

    标签: sql-server database multiple-insert


    【解决方案1】:

    我是一个 postgres 人,但是类似于下面的东西应该可以工作:

    insert into Program (user, program, installed, department, wheninstalled)
    select user, 
       'MyMostAwesomeProgram', 
       false, 
       (select department from someTable where u.user = ...),
       null
    from users as u;
    

    来自https://stackoverflow.com/a/23905173/3430807

    【讨论】:

      【解决方案2】:

      你说你知道怎么做选择

      insert into Program (user, program, installed, department, wheninstalled)
      select user, 'MyMostAwesomeProgram', 'false' , department, null 
      from ... 
      

      【讨论】:

        【解决方案3】:

        应该这样做:

        insert into Program (user, program, installed, department, whenInstalled)
        select user, program, installed, department, whenInstalled
        from 
        (
            select User
            , 'MyMostAwesomeProgram' program
            , 0 installed
            , department
            , null whenInstalled
            , row_number() over (partition by user order by whenInstalled desc, id desc) r
        from Program
        ) p
        where p.r = 1
        

        有趣的是row_number() over (partition by user order by whenInstalled desc, id desc) r

        这表示要返回一个列 r,它为每个 user 保存值 1..n,根据 order by 子句向上计数(即从最近的 whenInstalled 开始并向后工作)。

        我还在 order by 子句中包含了id 字段,以防同一用户在同一日期进行两次安装;在这种情况下,最近添加的(首先使用具有较高 id 的那个)。

        然后我们把它放在一个子查询中,并且只选择第一条记录;因此我们每个用户有 1 条记录,它是最新的。

        我们从这条记录中使用的唯一值是userdepartment 字段;其他所有内容都是根据您的默认值定义的。

        【讨论】:

        • ps。如果你想阅读它,这里有关于这个和类似功能的好博客。 blog.sqlauthority.com/2007/10/09/…
        • 非常感谢。您的查询对我最终完成工作帮助很大。现在我了解了分区与分组,那些短别名,最后我使用了一些排名函数,因为您的查询只返回了一行。但是有了排名,它就可以完美地工作:]。无论如何,对于那些可能会用谷歌搜索的人:
        【解决方案4】:

        所以我要为其他可能在谷歌上搜索的人回答这个问题:

        1. 要从一个表中获取一条记录到另一个表中,您需要使用 Select into 语句
        2. 我喜欢使用 With XXX 作为(一些选择)来指定,比如说,您可以在查询期间使用的“虚拟”表
        3. 正如 JohnLBevan 所指的非常有用的函数 Row_numberoverpartition by 而我错过的是一个 rank

        因此,一旦您阅读了这些内容,您应该能够理解如何做我想做的事情。

        【讨论】:

          猜你喜欢
          • 2018-03-01
          • 1970-01-01
          • 2010-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多