Insert into ... values ( SELECT ... FROM …)
Próbuję INSERT INTO
tabelę używając danych wejściowych z innej tabeli. Chociaż jest to całkowicie wykonalne dla wielu silników bazodanowych, zawsze wydaje mi się, że trudno zapamiętać poprawną składnię SQL
engine of the day (MySQL, Oracle, SQL Server, Informix i DB2).
Czy istnieje składnia silver-bullet pochodząca ze standardu SQL (na przykład SQL-92), która pozwoliłaby mi wstawić wartości bez martwienia się o baza danych?
22 answers
Try:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
Jest to standard ANSI SQL i powinien działać na dowolnym DBMS
Zdecydowanie działa dla:
- Oracle
- MS SQL Server
- MySQL
- Postgres
- SQLite v3
- Teradata
- DB2
- Sybase
- Vertica
- HSQLDB
- H2
- AWS RedShift
- SAP HANA
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 09:48:10
@Shadow_x99 : to powinno działać dobrze, a także możesz mieć wiele kolumn i inne dane:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
Edit: powinienem wspomnieć, że używałem tylko tej składni z Access, SQL 2000/2005/Express, MySQL i PostgreSQL, więc te powinny być uwzględnione. Komentator wskazał, że będzie działać z SQLite3.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:24
Aby uzyskać tylko jedną wartość w wartości multi INSERT
z innej tabeli zrobiłem następujące w SQLite3:
INSERT INTO column_1 ( val_1, val_from_other_table )
VALUES('val_1', (SELECT val_2 FROM table_2 WHERE val_2 = something))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-02 23:55:41
Obie odpowiedzi, które widzę, działają dobrze w Informixie i są w zasadzie standardowym SQL. Czyli zapis:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
Działa dobrze z Informix i, jak sądzę, wszystkie DBMS. (Kiedyś 5 lub więcej lat temu, to jest coś, co MySQL nie zawsze obsługiwał; teraz ma przyzwoite wsparcie dla tego rodzaju standardowej składni SQL i, AFAIK, to działa OK na tej notacji.) Lista kolumn jest opcjonalna, ale wskazuje kolumny docelowe w kolejności, więc pierwsza kolumna wyniku wyboru przejdzie do pierwszej z wymienionych kolumn, itd. W przypadku braku listy kolumn Pierwsza kolumna wyniku wyboru przechodzi do pierwszej kolumny tabeli docelowej.
To, co może być różne między systemami, to notacja używana do identyfikacji tabel w różnych bazach danych - standard nie ma nic do powiedzenia na temat operacji między bazami danych (nie mówiąc już o Inter-DBMS). Za pomocą Informix możesz użyć poniższej notacji, aby zidentyfikować Tabela:
[dbase[@server]:][owner.]table
Oznacza to, że możesz określić bazę danych, opcjonalnie określając serwer, na którym znajduje się baza danych, jeśli nie znajduje się ona na bieżącym serwerze, po którym następuje opcjonalny właściciel, kropka, a na końcu rzeczywista nazwa tabeli. Standard SQL używa terminu schema dla tego, co Informix nazywa właścicielem. Tak więc w Informix, każda z następujących notacji może zidentyfikować tabelę:
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
Właściciel w ogóle nie musi być cytowany; jednak, jeśli używasz cudzysłowów, musisz uzyskać nazwa właściciela pisana poprawnie - rozróżnia wielkość liter. Czyli:
someone.table
"someone".table
SOMEONE.table
Wszystkie identyfikują tę samą tabelę. W przypadku Informix występuje łagodna komplikacja z bazami danych MODE ANSI, w których nazwy właścicieli są zwykle konwertowane na wielkie litery (wyjątek stanowi informix). Oznacza to, że w trybie bazy danych ANSI (nie jest powszechnie używany) można napisać:
CREATE TABLE someone.table ( ... )
A nazwa właściciela w katalogu systemowym brzmiałaby "ktoś", a nie "ktoś". Jeśli umieścisz nazwę właściciela w podwójnych cudzysłowach, to działa jak oddzielony identyfikator. W przypadku standardowego SQL rozdzielone identyfikatory mogą być używane w wielu miejscach. W Informix można używać ich tylko przy nazwach właścicieli - w innych kontekstach Informix traktuje zarówno pojedynczo cytowane, jak i Podwójnie cytowane ciągi jako ciągi, zamiast oddzielać pojedynczo cytowane ciągi jako ciągi i Podwójnie cytowane ciągi jako rozdzielane identyfikatory. (Oczywiście dla kompletności istnieje zmienna środowiskowa DELIMIDENT, którą można ustawić-na dowolną wartość, ale y jest najbezpieczniejsze-na wskazuje, że podwójne cudzysłowy zawsze otaczają rozdzielone identyfikatory, a pojedyncze cudzysłowy zawsze otaczają ciągi znaków.)
Zauważ, że MS SQL Server potrafi używać [rozdzielonych identyfikatorów] ujętych w nawiasy kwadratowe. Dla mnie wygląda to dziwnie i na pewno nie jest częścią standardu SQL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-28 03:18:41
Większość baz danych opiera się na podstawowej składni,
INSERT INTO TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;
Każda baza danych, której użyłem, podąża za tą składnią, mianowicie, DB2
, SQL Server
, MY SQL
, PostgresQL
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-01 10:36:02
Aby dodać coś w pierwszej odpowiedzi, gdy chcemy tylko kilka rekordów z innej tabeli (w tym przykładzie tylko jeden):
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
VALUES (value1, value2,
(SELECT COLUMN_TABLE2
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-03 03:33:40
Można to zrobić bez podawania kolumn w części INSERT INTO
, jeśli podajesz wartości dla wszystkich kolumn w części SELECT
.
Załóżmy, że table1 ma dwie kolumny. To zapytanie powinno działać:
INSERT INTO table1
SELECT col1, col2
FROM table2
To nie zadziała (wartość dla col2
nie jest określona):
INSERT INTO table1
SELECT col1
FROM table2
Używam MS SQL Server. Nie wiem, jak działają inne RDM.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-16 14:19:52
To kolejny przykład użycia wartości z select:
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 09:12:35
Proste wstawianie, gdy znana jest kolejność kolumn tabeli:
Insert into Table1
values(1,2,...)
Proste wstawianie kolumny:
Insert into Table1(col2,col4)
values(1,2)
Wstawianie zbiorcze, gdy liczba wybranych kolumn tabeli (#table2) jest równa wstawianiu tabeli (Table1)
Insert into Table1 {Column sequence}
Select * -- column sequence should be same.
from #table2
Wstawianie zbiorcze, gdy chcesz wstawić tylko do żądanej kolumny tabeli (table1):
Insert into Table1 (Column1,Column2 ....Desired Column from Table1)
Select Column1,Column2..desired column from #table2
from #table2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-19 23:50:31
Zamiast VALUES
części INSERT
zapytania, po prostu użyj SELECT
zapytania jak poniżej.
INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 00:14:03
Oto Jak wstawić z wielu tabel. W tym konkretnym przykładzie znajduje się tabela mapowania w scenariuszu wielu do wielu:
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'
(zdaję sobie sprawę, że dopasowanie nazwy ucznia może zwrócić więcej niż jedną wartość, ale masz pomysł. Dopasowanie na czymś innym niż Id jest konieczne, gdy Id jest kolumną tożsamości i jest nieznany.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-23 16:34:55
Oto kolejny przykład, w którym źródło jest pobierane przy użyciu więcej niż jednej tabeli:
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;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 16:28:53
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;
To działa na wszystkich DBMS
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-20 08:44:14
To mi pomogło:
insert into table1 select * from table2
Zdanie jest nieco inne niż zdanie Oracle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 12:43:41
W przypadku Microsoft SQL Server zalecam naukę interpretacji składni dostarczonej na MSDN. Z Google jest to łatwiejsze niż kiedykolwiek, aby szukać składni.
W tym konkretnym przypadku spróbuj
Google: insert site:microsoft.com
Pierwszy wynik będzie http://msdn.microsoft.com/en-us/library/ms174335.aspx
Przewiń w dół do przykładu ("użycie opcji SELECT i EXECUTE do wstawiania danych z innych tabel"), jeśli masz trudności z interpretuje składnię podaną na górze strony.
[ 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
}
}
}
[;]
Powinno to mieć zastosowanie do wszelkich innych dostępnych tam systemów RDBM. Nie ma sensu zapamiętywać całej składni dla wszystkich produktów IMO.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-11 07:54:17
Możesz spróbować, jeśli chcesz wstawić wszystkie kolumny za pomocą tabeli SELECT * INTO
.
SELECT *
INTO Table2
FROM Table1;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-17 10:28:45
W SQL Server 2008 wolę następujące rzeczy:
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
Eliminuje to krok dodawania zestawu Insert (), a ty po prostu wybierasz, które wartości trafią do tabeli.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 14:57:06
select *
into tmp
from orders
Wygląda ładnie, ale działa tylko wtedy, gdy tmp nie istnieje (tworzy i wypełnia). (SQL sever)
Aby wstawić do istniejącej tabeli 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-18 13:36:12
Najlepszy sposób wstawiania wielu rekordów z innych tabel.
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-07 06:59:35
Wystarczy użyć nawiasu dla SELECT klauzuli w INSERT. Na przykład tak:
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'
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-24 09:25:16
Jeśli przejdziesz ścieżkę wstawiania wartości, aby wstawić wiele wierszy, upewnij się, że wartości są rozdzielane na zestawy za pomocą nawiasów, więc:
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');
W Przeciwnym Razie Obiekty MySQL, które "Liczba kolumn nie pasuje do liczby wartości w wierszu 1", a ty piszesz trywialny post, gdy w końcu wymyślisz, co z tym zrobić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 03:51:51
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 00:14:28