Jak wstawić jednocześnie wiele wartości do tabeli postgres?

93

Mam tabelę, którą próbuję zaktualizować wiele wartości jednocześnie. Oto schemat tabeli:

    Column     |  Type   | Modifiers 
---------------+---------+-----------
 user_id       | integer | 
 subservice_id | integer |

Mam user_idi chcę wstawić wiele subservice_idplików jednocześnie. Czy jest w Postgrestym składnia , która pozwoli mi zrobić coś takiego

insert into user_subservices(user_id, subservice_id) values(1, [1, 2, 3]);

Jak bym to zrobił?

jhamm
źródło
1
Jeśli chcesz wstawić je z sekwencji lub używając, generate_serieszobacz dba.stackexchange.com/a/89544/16892
rogerdpack

Odpowiedzi:

172

Składnia wstawiania wielu wartości to:

insert into table values (1,1), (1,2), (1,3), (2,1);

Ale odpowiedź krokodilko jest znacznie lepsza.

Scott Marlowe
źródło
Czy w przypadku którejkolwiek z tych metod istnieje sposób zwrócenia również id?
dvtan
2
Tak, użyj zwrotu. "wstaw do tabeli (id, yada) wartości (1,2), (9,22) zwracanie id;" itd.
Scott Marlowe,
1
Również w dzisiejszych czasach często dobrze działa instrukcja CTE aka WITH.
Scott Marlowe
Wartości całkowite można wstawiać jak powyżej. Ale podczas wstawiania tekstu przy użyciu powyższej metody pojawia się błąd, taki jak kolumna nie istnieje. insert into orders_cancel_reasons_infos values (1,1,"Changed my mind",1), (2,2,"Quality not satisfactory",1), (3,3,"Incompatible or not useful",1), (4,4,"Damaged product but shipping box is good",1), (5,5,"Items arrived too late",1), (6,6,"Missing part or accessories",1), (7,7,"Product and shipping box are damaged",1), (8,8,"Wrong item was sent",1), (9,9,"Defective item",1), (10,10,"Inaccurate description",1), (11,11,"Other",1);
sankar muniyappa
@sankarmuniyappa będziesz musiał użyć pojedynczych cudzysłowów ' 'dla wstawianego tekstu. więc coś w stylu insert into orders_cancel_reasons_infos values (1,1,'Changed my mind',1), (2,2,'Quality not satisfactory',1)będzie działać. Można sprawdzić to na więcej pojedynczych i podwójnych cudzysłowów.
dr0pdb
25

Krótsza wersja odpowiedzi Krokodilko:

insert into user_subservices(user_id, subservice_id) 
values(1, unnest(array[1, 2, 3]));
yallie
źródło
Myślę, że jest to bardziej wyrazisty zamiar niż akceptowana odpowiedź. Czy ten standardowy SQL czy PostgreSQL jest specyficzny?
Bernard
3
Obie odpowiedzi są specyficzne dla PostgreSQL. Odpowiedź akceptowana jest chyba łatwiej tłumaczone do innych baz danych Oracle na przykład: insert into user_subservices(user_id, subservice_id) select 1, column_value from table(sys.odcinumberlist(1,2,3)).
yallie
Dzięki, ma to o wiele więcej sensu i jest bardziej czytelne niż zaakceptowana moim zdaniem odpowiedź.
mroźny
1
Sposób wykorzystania tego z informacjami z innej tabeli: insert into user_subservices(user_id, subservice_id) values(1, unnest(ARRAY(select id from subservices where name like '%test%')));
Efren
12

Trochę pokrewna odpowiedź, ponieważ za każdym razem, gdy próbuję zapamiętać to rozwiązanie, napotykam to pytanie. Wstaw wiele wierszy z wieloma kolumnami :

insert into user_subservices (user_id, subservice_id)
select *
from unnest(array[1, 2], array[3, 4]);
Andreas Hultgren
źródło
3

Bardziej solidny przykład, gdy trzeba wstawić wiele wierszy do jednej tabeli dla każdego wiersza w innej tabeli:

INSERT INTO user_subservices (user_id, subservice_id)
SELECT users.id AS user_id, subservice_id
FROM users
CROSS JOIN unnest(ARRAY[1,2,3]) subservice_id;
Envek
źródło