Сведения о вопросе

Faridun

08:30, 11th August, 2020

Теги

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

Просмотров: 454   Ответов: 23

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

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



  Сведения об ответе

padenie

12:01, 3rd August, 2020

Попробуй:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Это стандартный ANSI SQL и должен работать на любом DBMS

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

  • Oracle
  • MS SQL сервер
  • MySQL
  • Постгреса
  • SQLite В3
  • Teradata
  • DB2
  • Sybase
  • Решение Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP хана


  Сведения об ответе

piter

20:06, 29th August, 2020

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

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

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


  Сведения об ответе

baggs

21:06, 1st October, 2020

Чтобы получить только одно значение в многозначном 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))


  Сведения об ответе

padenie

18:53, 25th August, 2020

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

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

отлично работает с Informix и, как я ожидаю, со всеми DBMS. (Когда-то, 5 или более лет назад, это такая вещь, которую MySQL не всегда поддерживал; теперь он имеет приличную поддержку для такого стандартного синтаксиса SQL и, AFAIK, он будет работать OK на этой нотации.) Список столбцов является необязательным, но указывает целевые столбцы в последовательности, поэтому первый столбец результата SELECT перейдет в первый столбец списка и т. д. При отсутствии списка столбцов первый столбец результата SELECT переходит в первый столбец целевой таблицы.

Что может отличаться между системами, так это нотация, используемая для идентификации таблиц в разных базах данных - стандарт ничего не говорит об операциях между базами данных (не говоря уже об операциях между DBMS). В случае 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 (обычно не используется) можно было бы написать:

CREATE TABLE someone.table ( ... )

и имя владельца в системном каталоге будет "SOMEONE", а не 'someone'. Если вы заключаете имя владельца в двойные кавычки, оно действует как разделенный идентификатор. В стандарте SQL разделенные идентификаторы могут использоваться во многих местах. В случае Informix вы можете использовать их только вокруг имен владельцев - в других контекстах Informix обрабатывает как строки в одинарных, так и в двойных кавычках как строки, а не разделяет строки в одинарных кавычках как строки и строки в двойных кавычках как разделенные идентификаторы. (Конечно, для полноты описания существует переменная окружения DELIMIDENT, которая может быть установлена - в любое значение, но Y безопаснее всего - чтобы указать, что двойные кавычки всегда окружают разделенные идентификаторы, а одиночные кавычки всегда окружают строки.)

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


  Сведения об ответе

davran

04:23, 17th August, 2020

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

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

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


  Сведения об ответе

appple

19:04, 16th August, 2020

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

INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
VALUES (value1, value2, 
(SELECT COLUMN_TABLE2 
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);


  Сведения об ответе

screen

17:28, 19th August, 2020

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

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

INSERT INTO table1
SELECT  col1, col2
FROM    table2

Это не сработает (значение для col2 не указано):

INSERT INTO table1
SELECT  col1
FROM    table2

Я использую сервер MS SQL. Я не знаю, как работают другие RDMS.


  Сведения об ответе

PROGA

11:19, 7th August, 2020

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

INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2


  Сведения об ответе

nYU

11:46, 21st August, 2020

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

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...


  Сведения об ответе

прога

06:10, 8th August, 2020

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

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

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

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

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

    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


  Сведения об ответе

SILA

05:55, 19th August, 2020

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

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;


  Сведения об ответе

lats

18:58, 26th August, 2020

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

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'

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


  Сведения об ответе

PIRLO

11:38, 1st August, 2020

INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

Это работает на всех DBMS


  Сведения об ответе

ASER

01:27, 27th August, 2020

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

SELECT  *
INTO    Table2
FROM    Table1;


  Сведения об ответе

KOMP

20:47, 1st August, 2020

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

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

Google: вставить site: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 
        }
    }
}
[;]

Это должно быть применимо к любому другому RDBMS, имеющемуся там. Нет смысла запоминать весь синтаксис для всех продуктов IMO.


  Сведения об ответе

$DOLLAR

04:46, 20th August, 2020

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

insert into table1 select * from table2

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


  Сведения об ответе

crush

09:01, 26th August, 2020

На самом деле я предпочитаю следующее в 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 (), и вы просто выбираете, какие значения идут в таблице.


  Сведения об ответе

DAAA

02:01, 21st August, 2020

Просто используйте скобки для 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'
);


  Сведения об ответе

lesha

18:04, 23rd August, 2020

select *
into tmp
from orders

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

Чтобы вставить в существующую таблицу 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


  Сведения об ответе

qwerty101

17:48, 12th August, 2020

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

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)


  Сведения об ответе

#hash

05:25, 12th August, 2020

INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;


  Сведения об ответе

прога

06:50, 12th August, 2020

Два подхода для вставки в с помощью подзапроса select.

  1. С подзапросом SELECT, возвращающим результаты с одной строкой .
  2. С подзапросом SELECT, возвращающим результаты с несколькими строками .

1. Подход с SELECT подзапрос, возвращающий результаты в одну строку .

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');

В этом случае предполагается, что подзапрос SELECT возвращает только одну строку результата на основе условия WHERE или агрегатных функций SQL, таких как SUM, MAX, AVG и т. д. В противном случае он выдаст ошибку

2. Подход с SELECT подзапрос, возвращающий результаты с нескольких строк .

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;

Второй подход будет работать в обоих случаях.


  Сведения об ответе

qwerty101

19:27, 18th August, 2020

Если вы идете по маршруту вставки значений, чтобы вставить несколько строк, убедитесь, что 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", и вы в конечном итоге пишете тривиальный пост, когда наконец выясните, что с этим делать.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться