Aven
22.08.2003, 11:57:03
witam,
podczas pisania pewnego projektu natknalem sie oczywiscie na cos czego nie potrafie zrobic w "ładny sposób".
chce przerzucic z jednej tabeli do drugiej pewne wartosci z pól. Nie sa to wszystkie wartosci, tylko okreslone (i nie sa w tej samej kolejnosci).
w manualu MySQL jest skladnia INSERT SELECT, ktora w zasadzie powinna rozwiazac moj problem, ale widac zle jej uzywam :-(
mam cos takiego :
Kod
$zapytanie="INSERT INTO tabela2 VALUES ('id','partner','id','email','nazwa','link','katalog') SELECT FROM tabela1 WHERE partner='$ident";
tabele maja rozna ilosc pol.
wartosc pierwsza id to autoinkrementacja, a druga id to wartosc którą chcialbym pobrac z tabeli1. (wiem ze to co napisalem jest zle

)
Mozna to oczywiscie zrobic w petli dwoma zapytaniami, ale czasami warto sobie utrudnic :-)
Prosze wszystkich "wiedzacych" jak zadac takie zapytanie o pomoc.
uboottd
22.08.2003, 12:15:12
[sql:1:187cfbcd69]
INSERT INTO tabela2
(id, partner, inny_id, email, nazwa, link, katalog)
SELECT NULL, partner, id, email, nazwa, link, katalog
FROM tabela1 WHERE
partner='$ident'
[/sql:1:187cfbcd69]
Uwagi:
- po nazwie tabeli wystepuja nazwy z tabeli do ktorej wsadzasz wiec istnienie tam dwa razy id jest bez sensu, zalozylem ze pole nazywa sie id a to drugie to inny_id - dostosuj sobie
- jesli pole jest autoincrement to mozesz albo je po prostu pominac w liscie pol, albo wsadzac tam wartosc NULL jak masz w przykladzie - wtedy zostanie wsadzona nastepna wartosc generowana
- ilosc pol po tabela2 i w SELECTcie musi byc taka sama i w tej samej kolejnosci - sa one w tej kolejnosci przypisywane
- dla mysql <4.0.14 nie mozna robic SELECT-a do bazy do ktorej INSERT-ujesz
Aven
22.08.2003, 13:30:07
dzieki za pomoc ...
pozmienialem, wyprobowalem i ... :-(
[sql:1:9298c11d4f]
INSERT INTO newsletter
VALUES (id, partner_id, link_id, email, nazwa, link, kategoria)
SELECT NULL, partner, id, email, nazwa, link, katalog
FROM tabela
WHERE partner='$identyfikator'
[/sql:1:9298c11d4f]
1064
You have an error in your SQL syntax near 'SELECT NULL, partner, id, email, nazwa, link, katalog FROM tabela WHERE partne' at line 3
1064 to jest PARSE ERROR :-(
liczba w values i select sie zgadza. probowalem bez nulla i id. probowalem bez nawiasow, z nawiasami eh :-(.
- nazwy w values i select sa takie jak faktyczne kolumny w tabelach.
- kolejnosc jest tez dobra
co tu jest nie tak ? :-)
pozdrawiam
uboottd
22.08.2003, 13:38:55
[sql:1:331131b8dc]
INSERT INTO newsletter (id, partner_id, link_id, email, nazwa, link, kategoria)
SELECT NULL, partner, id, email, nazwa, link, katalog
FROM tabela WHERE partner='$identyfikator'
[/sql:1:331131b8dc]
Skad wytrzasnales to VALUES u siebie ?
Skladnia jest INSERT INTO ... SELECT ...
A nie INSERT INTO ... VALUES ... SELECT ...
Aven
22.08.2003, 13:53:13
faktycznie nie wiem skad to wzialem :-)
teraz dziala bez zarzutów
dzieki wielkie !!!!!
Aven
22.08.2003, 15:20:42
do glowy wpadl mi jeszcze jeden pomysl ...
czy da sie sformulowac to zapytanie do bazy tak zeby jednoczesnie sprawdzalo czy gdzies w tabeli docelowej nie ma juz wpisu ktory ma byc do niej dodany?
chodzi o to zeby do tabeli docelowej nie trafialy dwa razy te same rekordy.
czy w mysql jest wogole taka skladnia ktora na to pozwala ?
jesli nie ma to niestety bede musial i tak robic wszystko jeszcze raz kilkoma zapytaniami w php :-(
pozdrawiam
Jabol
22.08.2003, 15:22:46
indexy unique?
uboottd
22.08.2003, 19:17:05
Jabol: nie chodzi o wywalenie zapytania, ale o wstawienie tylko potrzebnych indeksow.
Da sie, ale po pierwse mysql 4.0.14 dopiero to wspiera i jest to ze wzgledu na brak podzapytan dosc trudne i zagrzybione. Mam to poskladac ?
Aven
22.08.2003, 19:20:09
w zasadzie na serwie na ktorym sie to znajduje jest chyba nawet wyzsza wersja php.
mysle jednak ze jest to i tak nie na moja glowe, wiec sobie juz poradzilem inaczej :-)
Jabol
22.08.2003, 19:20:13
ubootd: kazdy sposob jest dobry
a wogole to mozna to zrobic tak:
wczesci select dac podselect (jak powiedzaj ubootd)[sql:1:79672ebea6]WHERE id not in ( select id from table );[/sql:1:79672ebea6]
//edit
ubottd:ahhh i znowy tylko przeglodam posty... pokarz jak bo sam jestem ciekawy
uboottd
22.08.2003, 21:04:29
A bos dawno mysqla nie mial i sie Ci w d... poprzewracalo !
[sql:1:8f678cebe9]
insert into tabela2 (pola...)
select pola...
from tabela1 left join tabela2 on tabela1_id = tabela2_id
where tabela2_id is null;
[/sql:1:8f678cebe9]
Aven: wersja mysql-a nie php-a. Nie ma w tej chwili oficjalnego mysql-a wyzszego od 4.0.14.
Jabol
22.08.2003, 21:05:54
uboottd: ale to musialbys dac outer joina?
uboottd
22.08.2003, 21:13:26
Mozna prosic calym zdaniem ?
Jabol
22.08.2003, 21:24:13
Aby osiagnoc zamierzony przez Ciebie efekt join wymaga byc outer joinem (a AFAIK defaultowy to inner join) wiec skladnia powinna byc.[sql:1:aa7b797628]INSERT INTO tabela2 (pola...)
SELECT pola...
FROM tabela1 LEFT OUTER join tabela2 ON (tabela1_id = tabela2_id)
WHERE tabela2_id IS NULL;[/sql:1:aa7b797628]Tak conajmniej mi sie wydaje.
przy inner joinach nie daje nulla przy łączeniu tylko po prostu nie łączy pól bez odpowieników.
uboottd
22.08.2003, 21:38:43
W zasadzie a i owszem, ale nie do konca. Widzisz jakas zasadnosc zapisu LEFT INNER JOIN ? Bo zapis ten jest zreszta nielegalny. Wiec slowko OUTER staje sie w tym momencie opcjonalnym dodatkiem - sklejenie i tak jest outer.
A, i lacza sie wiersze a nie pola
Jabol
22.08.2003, 21:43:10
chyba rzeczywiscie dawno mysql nie mialem (za dawno ... ). Ale jak ktos kiedys mondrze powiedzial (nie o tym, ale to szczegół), "w jedną stronę trudno, w drugą niemożliwe".
uboottd
22.08.2003, 21:47:54
W obie strony mozna, trza tylko pamietac o zwyczajach.
postgres tez nie przyjmie Ci left inner join.
Jabol
22.08.2003, 21:50:41
ale "left join" oznacza "inner join" o ile wiem na mysqlu? a ogolnie to wlasciwie nie wiem... kurcze, bo w mysqlu left i right join to to samo, czyli są inner, ale w postgresie chyba rzeczywiście defaultowo jest outer w takich przypadkach i dla inner trzeba napisac inner albo lanczyc przez where.
uboottd
22.08.2003, 21:58:41
Dobra, to jasno i prosto:
Sklejenie mozebyc _albo_ INNER _albo_ jedno z LEFT, RIGHT, FULL ktore moga byc tylko i wylacznie OUTER. I podanie OUTER jest opcjonalne bo nic nie zmienia. Mozna inaczej powiedziec ze LEFT, RIGTH i FULL sa rodzajami sklejenia OUTER.
I dotyczy to wszystkich normalnych serwerow bazodanowych (a co namniej Oracla, MySQL-a i PostgreSQL-a) bo wynika to z teorii.
A, i powalilo ? na Mysqlu LEFT i RIGHT nie jest jednoznaczne. Oznacza dokladnie to co powinno..
Jabol
22.08.2003, 22:11:47
1 ostatnio mało sypiam ;P
2 ktos ostatnio na forum cytował manuala
3 zostawmy ten temat bo cos mi sie mieszac zaczyna
adwol
22.08.2003, 22:16:34
Cytat
ale "left join" oznacza "inner join" o ile wiem na mysqlu?
Nie, w mysqlu left join to left join czyli złączenie zewnętrzne lewe, a inner to inner czyli wewnętrzne.
Cytat
a ogolnie to wlasciwie nie wiem... kurcze, bo w mysqlu left i right join to to samo, czyli są inner
Chyba jednak nie.
Cytat
ale w postgresie chyba rzeczywiście defaultowo jest outer w takich przypadkach i dla inner trzeba napisac inner albo lanczyc przez where.
Nie. Domyślnie w pg słowo kluczowe
JOIN daje złączenie wewnętrzne.
CROSS JOIN albo najpopularniejszy przecinek daje kartezjańskie (które po dodaniu warunku po WHERE staje się wewnętrznym), a zewnętrzne należy wymusić przez podanie
LEFT,
RIGHT lub
FULL i opcjonalnie po nim
OUTER.
Polecam poczytać o typach złączeń:
http://www.postgresql.org/docs/7.3/static/...expressions.html
uboottd
22.08.2003, 22:16:49
ad 1. Z tym Ci nie pomoge.
ad 2. To nie wiem jak on cytowal:
"RIGHT JOIN works analogously as LEFT JOIN." - Analogicznie nie oznacza tak samo.
Jabol
22.08.2003, 22:22:01
jezeli chodzi o pg to ja to znam, po prostu miesza mi sie z tym mysql'em. brrr... dobrze, postanowienie. nie wypowiadam się więcej na tematy o mysql'u, bo kurka tylko ludzi w błąd wprowadzam.
ps.
no wlasnie, jedno slowko...
piratt
29.09.2005, 00:01:22
Witam wszystkich.
Mam male pytanko;) dotyczace INSERT.. SELECT'a.
INSERT `bgraczy` (idGracza,idBudynku,poziomBudynku) SELECT gracze.id,budynki.id,1 FROM gracze,budynki WHERE gracze.nick='gracz' and budynki.shortnazwa='Rada1';
Ta kwerenda dziala bardzo dobrze, jednak problem pojawia sie gdy obie dodawane wartosci maja pochodzic z tego samego pola z tej samej tabeli(roznia sie tylko rekordy). Napisalem takie cos:
INSERT `wymbud` (idBudynku,idBudynkuWym,pozBudynkuWym) SELECT budynki.id,cos.id,'1' FROM budynki as cos INNER JOIN budynki WHERE budynki.shortnazwa='Wojenny3' AND cos.shortnazwa='Wojenny2';
Czy da sie to napisac w jakis prostszy sposob?
Pozdrawiam
Michał
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.