Вставить в ... значения (SELECT ... FROM ...)

Я пытаюсь сделать INSERT INTO таблицы, используя ввод из другой таблицы. Хотя это вполне возможно для многих механизмов баз данных, я всегда стараюсь запомнить правильный синтаксис для SQL движка дня ( MySQL , Oracle , SQL Server , Informix и DB2 ).

Существует ли синтаксис с серебряной пулей, исходящий из стандарта SQL (например, SQL-92 ), который позволит мне вставлять значения, не беспокоясь о базовой базе данных?

вопрос задан 25.08.2008
Claude Houle
21063 репутация

22 ответов


  • 0 рейтинг

    Вот как вставить из нескольких таблиц. В этом конкретном примере вы найдете таблицу сопоставления во многих сценариях:

     insert into StudentCourseMap (StudentId, CourseId) 
    SELECT  Student.Id, Course.Id FROM Student, Course 
    WHERE Student.Name = 'Paddy Murphy' AND Course.Name = 'Basket weaving for beginners'
     

    (Я понимаю, что сопоставление имени студента может возвращать более одного значения, но вы получаете идею. Соответствие чему-то, кроме идентификатора, необходимо, когда Id является столбцом Identity и неизвестно.)

    ответ дан Ciaran Bruen, с репутацией 3590, 23.03.2016
  • 0 рейтинг

    Большинство баз данных соответствуют основному синтаксису,

     INSERT INTO TABLE_NAME
    SELECT COL1, COL2 ...
    FROM TABLE_YOU_NEED_TO_TAKE_FROM
    ;
     

    Каждая база данных, которую я использовал, следует этому синтаксису: DB2 , SQL Server , MY SQL , PostgresQL

    ответ дан Santhosh, с репутацией 1486, 1.04.2013
  • 0 рейтинг

    Чтобы получить только одно значение из нескольких значений INSERT из другой таблицы, я сделал следующее в SQLite3:

     INSERT INTO column_1 ( val_1, val_from_other_table ) 
    VALUES('val_1', (SELECT  val_2 FROM table_2 WHERE val_2 = something))
     
    ответ дан kylie.a, с репутацией 6974, 10.01.2014
  • 0 рейтинг

    Простая вставка, когда последовательность столбцов таблицы известна:

         Insert into Table1
        values(1,2,...)
     

    Простая колонка с указанием вставки:

         Insert into Table1(col2,col4)
        values(1,2)
     

    Массовая вставка, когда количество выбранных столбцов таблицы (# table2) равно таблице вставки (Таблица 1)

         Insert into Table1 {Column sequence}
        Select * -- column sequence should be same.
           from #table2
     

    Массовая вставка, если вы хотите вставить только в нужный столбец таблицы (таблица 1):

         Insert into Table1 (Column1,Column2 ....Desired Column from Table1)  
        Select Column1,Column2..desired column from #table2
           from #table2
     
    ответ дан RameezAli, с репутацией 688, 13.02.2014
  • 0 рейтинг

    Это можно сделать без указания столбцов в INSERT INTO части, если вы поставляете значения для всех столбцов в SELECT части.

    Скажем, таблица1 имеет два столбца. Этот запрос должен работать:

     INSERT INTO table1
    SELECT  col1, col2
    FROM    table2
     

    Это НЕ РАБОТАЕТ (значение для col2 не указано):

     INSERT INTO table1
    SELECT  col1
    FROM    table2
     

    Я использую MS SQL Server. Я не знаю, как работает другая СУБД.

    ответ дан northben, с репутацией 3114, 16.10.2012
  • 0 рейтинг

    Просто используйте скобки для предложения SELECT в INSERT. Например, например:

     INSERT INTO Table1 (col1, col2, your_desired_value_from_select_clause, col3)
    VALUES (
       'col1_value', 
       'col2_value',
       (SELECT col_Table2 FROM Table2 WHERE IdTable2 = 'your_satisfied_value_for_col_Table2_selected'),
       'col3_value'
    );
     
    ответ дан Dasikely, с репутацией 92, 24.09.2018
  • 0 рейтинг

    Это сработало для меня:

     insert into table1 select * from table2
     

    Предложение немного отличается от предложения Oracle.

    ответ дан elijah7, с репутацией 101, 20.11.2013
  • 0 рейтинг

    Пытаться:

     INSERT INTO table1 ( column1 )
    SELECT  col1
    FROM    table2  
     

    Это стандартный ANSI SQL и должен работать на любой СУБД

    Это определенно работает для:

    • оракул
    • MS SQL Server
    • MySQL
    • Postgres
    • SQLite v3
    • Teradata
    • DB2
    • Sybase
    • Vertica
    • HSQLDB
    • H2
    • AWS RedShift
    • SAP HANA
    ответ дан Claude Houle, с репутацией 21063, 25.08.2008
  • 0 рейтинг
     INSERT INTO yourtable
    SELECT fielda, fieldb, fieldc
    FROM donortable;
     

    Это работает во всех СУБД

    ответ дан Matt, с репутацией 10604, 20.05.2015
  • 0 рейтинг

    Вот еще один пример, когда источник берется с использованием более чем одной таблицы:

     INSERT INTO cesc_pf_stmt_ext_wrk( 
      PF_EMP_CODE    ,
      PF_DEPT_CODE   ,
      PF_SEC_CODE    ,
      PF_PROL_NO     ,
      PF_FM_SEQ      ,
      PF_SEQ_NO      ,
      PF_SEP_TAG     ,
      PF_SOURCE) 
    SELECT
      PFl_EMP_CODE    ,
      PFl_DEPT_CODE   ,
      PFl_SEC         ,
      PFl_PROL_NO     ,
      PF_FM_SEQ       ,
      PF_SEQ_NO       ,
      PFl_SEP_TAG     ,
      PF_SOURCE
     FROM cesc_pf_stmt_ext,
          cesc_pfl_emp_master
     WHERE pfl_sep_tag LIKE '0'
       AND pfl_emp_code=pf_emp_code(+);
    
    COMMIT;
     
    ответ дан SWATI BISWAS, с репутацией 159, 6.06.2012
  • 0 рейтинг
    INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
    SELECT  COLUMN_NAME
    FROM    ANOTHER_TABLE_NAME 
    WHERE CONDITION;
    
    ответ дан Gaurav, с репутацией 74, 13.02.2018
  • 0 рейтинг

    Для Microsoft SQL Server я рекомендую научиться интерпретировать SYNTAX, предоставленный в MSDN. С Google проще, чем когда-либо, искать синтаксис.

    В этом конкретном случае попробуйте

    Google: вставить сайт: microsoft.com

    Первым результатом будет http://msdn.microsoft.com/en-us/library/ms174335.aspx

    прокрутите вниз до примера («Использование опций SELECT и EXECUTE для вставки данных из других таблиц»), если вам трудно интерпретировать синтаксис, указанный в верхней части страницы.

     [ WITH <common_table_expression> [ ,...n ] ]
    INSERT 
    {
            [ TOP ( expression ) [ PERCENT ] ] 
            [ INTO ] 
            { <object> | rowset_function_limited 
              [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
            }
        {
            [ ( column_list ) ] 
            [ <OUTPUT Clause> ]
            { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n     ] 
            | derived_table       <<<<------- Look here ------------------------
            | execute_statement   <<<<------- Look here ------------------------
            | <dml_table_source>  <<<<------- Look here ------------------------
            | DEFAULT VALUES 
            }
        }
    }
    [;]
     

    Это должно быть применимо для любых доступных СУБД. Нет смысла вспоминать весь синтаксис для всех продуктов IMO.

    ответ дан Faiz, с репутацией 3013, 17.10.2012
  • 0 рейтинг

    Вместо VALUES части INSERT запроса просто используйте SELECT запроса, как показано ниже.

     INSERT INTO table1 ( column1 , 2, 3... )
    SELECT col1, 2, 3... FROM table2
     
    ответ дан logan, с репутацией 3110, 21.04.2015
  • 0 рейтинг

    Чтобы добавить что-то в первый ответ, когда нам нужно всего несколько записей из другой таблицы (в этом примере только один):

     INSERT INTO TABLE1
    (COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
    VALUES (value1, value2, 
    (SELECT COLUMN_TABLE2 
    FROM TABLE2
    WHERE COLUMN_TABLE2 like "blabla"),
    value4);
     
    ответ дан Weslor, с репутацией 15224, 9.04.2015
  • 0 рейтинг
     select *
    into tmp
    from orders
     

    Выглядит неплохо, но работает только в том случае, если tmp не существует (создает его и заполняет). (SQL sever)

    Чтобы вставить в существующую таблицу tmp:

     set identity_insert tmp on
    
    insert tmp 
    ([OrderID]
          ,[CustomerID]
          ,[EmployeeID]
          ,[OrderDate]
          ,[RequiredDate]
          ,[ShippedDate]
          ,[ShipVia]
          ,[Freight]
          ,[ShipName]
          ,[ShipAddress]
          ,[ShipCity]
          ,[ShipRegion]
          ,[ShipPostalCode]
          ,[ShipCountry] )
          select * from orders
    
    set identity_insert tmp off
     
    ответ дан Pavel, с репутацией 113, 17.05.2014
  • 0 рейтинг

    Я действительно предпочитаю следующее в SQL Server 2008:

     SELECT Table1.Column1, Table1.Column2, Table2.Column1, Table2.Column2, 'Some String' AS SomeString, 8 AS SomeInt
    INTO Table3
    FROM Table1 INNER JOIN Table2 ON Table1.Column1 = Table2.Column3
     

    Это исключает шаг добавления набора Insert (), и вы просто выбираете, какие значения идут в таблице.

    ответ дан Grungondola, с репутацией 464, 22.03.2013
  • 0 рейтинг

    Лучший способ вставить несколько записей из любых других таблиц.

     INSERT  INTO dbo.Users
                ( UserID ,
                  Full_Name ,
                  Login_Name ,
                  Password
                )
                SELECT  UserID ,
                        Full_Name ,
                        Login_Name ,
                        Password
                FROM    Users_Table
                (INNER JOIN / LEFT JOIN ...)
                (WHERE CONDITION...)
                (OTHER CLAUSE)
     
    ответ дан Manish Vadher, с репутацией 424, 7.06.2018
  • 0 рейтинг

    Оба ответа, которые я вижу, отлично работают в Informix, и в основном являются стандартными SQL. То есть, обозначение:

     INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
     

    отлично работает с Informix и, я бы ожидал, всей СУБД. (Однажды 5 или более лет назад, это то, что MySQL не всегда поддерживал, теперь он имеет достойную поддержку такого стандартного синтаксиса SQL и AFAIK, он будет работать нормально в этой нотации.) Список столбцов необязательно, но указывает целевые столбцы в последовательности, поэтому первый столбец результата SELECT войдет в первый указанный столбец и т. д. В отсутствие списка столбцов первый столбец результата SELECT переходит в первый столбец целевой таблицы.

    То, что может быть различным между системами, - это нотация, используемая для идентификации таблиц в разных базах данных - стандарт не имеет ничего общего с межбанковскими операциями (не говоря уже о СУБД). В Informix вы можете использовать следующие обозначения для идентификации таблицы:

     [dbase[@server]:][owner.]table
     

    То есть вы можете указать базу данных, опционально идентифицирующую сервер, на котором размещена эта база данных, если она отсутствует на текущем сервере, за которой следует необязательный владелец, точка и, наконец, фактическое имя таблицы. В стандарте SQL используется термин схема, для которой Informix вызывает владельца. Таким образом, в Informix любое из следующих обозначений может идентифицировать таблицу:

     table
    "owner".table
    dbase:table
    dbase:owner.table
    dbase@server:table
    dbase@server:owner.table
     

    Владельцу вообще не нужно указывать; однако, если вы используете кавычки, вам нужно правильно ввести имя владельца - оно будет чувствительным к регистру. То есть:

     someone.table
    "someone".table
    SOMEONE.table
     

    все идентифицируют одну и ту же таблицу. С Informix существует мягкое осложнение с базами данных MODE ANSI, где имена владельцев обычно преобразуются в верхний регистр (исключение является Informix). То есть в базе данных ANSI MODE (обычно не используется) вы можете написать:

     CREATE TABLE someone.table ( ... )
     

    и имя владельца в системном каталоге будет «ЧЕЛОВЕК», а не «кто-то». Если вы введете имя владельца в двойные кавычки, он будет действовать как разделительный идентификатор. Со стандартным SQL идентификаторы с разделителями могут использоваться во многих местах. В Informix вы можете использовать их только по именам владельцев - в других контекстах Informix рассматривает как строки с одиночными кавычками, так и строки с двойными кавычками в виде строк, вместо того, чтобы разделять строки с одним кадром как строки и строки с двумя кавычками в качестве идентификаторов с разделителями. (Разумеется, для полноты есть переменная среды DELIMIDENT, которая может быть установлена ​​на любое значение, но Y является самым безопасным - для указания того, что двойные кавычки всегда содержат разделительные идентификаторы, а одинарные кавычки всегда окружают строки).

    Обратите внимание, что MS SQL Server удается использовать [ограниченные идентификаторы], заключенные в квадратные скобки. Это выглядит странно для меня и, конечно же, не является частью стандарта SQL.

    ответ дан Jonathan Leffler, с репутацией 546469, 28.09.2008
  • 0 рейтинг

    Это еще один пример использования значений с помощью select:

     INSERT INTO table1(desc, id, email) 
    SELECT "Hello World", 3, email FROM table2 WHERE ...
     
    ответ дан Sarvar Nishonboyev, с репутацией 3145, 20.03.2014
  • 0 рейтинг

    Вы можете попробовать это, если хотите вставить весь столбец, используя таблицу SELECT * INTO .

     SELECT  *
    INTO    Table2
    FROM    Table1;
     
    ответ дан Bharath theorare, с репутацией 340, 17.06.2016
  • 0 рейтинг

    @ Shadow_x99 : Это должно работать нормально, и вы также можете иметь несколько столбцов и других данных:

     INSERT INTO table1 ( column1, column2, someInt, someVarChar )
    SELECT  table2.column1, table2.column2, 8, 'some string etc.'
    FROM    table2
    WHERE   table2.ID = 7;
     

    Редактирование: Следует упомянуть, что я использовал этот синтаксис только с Access, SQL 2000/2005 /Express, MySQL и PostgreSQL, поэтому они должны быть охвачены. Один из комментаторов отметил, что он будет работать с SQLite3.

    ответ дан travis, с репутацией 24995, 25.08.2008
  • 0 рейтинг

    Если вы запустите маршрут INSERT VALUES, чтобы вставить несколько строк, обязательно разделите VALUES на группы с помощью круглых скобок, чтобы:

     INSERT INTO `receiving_table`
      (id,
      first_name,
      last_name)
    VALUES 
      (1002,'Charles','Babbage'),
      (1003,'George', 'Boole'),
      (1001,'Donald','Chamberlin'),
      (1004,'Alan','Turing'),
      (1005,'My','Widenius');
     

    В противном случае MySQL указывает, что «Количество столбцов не соответствует количеству значений в строке 1», и вы в конечном итоге пишете тривиальный пост, когда вы, наконец, выясните, что с ним делать.

    ответ дан Sebastian, с репутацией 90, 9.06.2017