» »

[SQL] Insert

[SQL] Insert

greentech ::

Imam en problem z insert oz. z dupliciranjem podatkov v tabelah
SQL stavek zgleda takole

INSERT INTO table3(tid,mid,parent_id) SELECT t1.id, t2.id, t3.id FROM table1 AS t1, table2 AS t2, table3 AS t3

Vrednosti v tabelah

table1(t1)|table2(t2)|table3(t3)|
111
22
33
44
55
66


Dodani podatki v table3 potem zgledajo takole:

tid|mid|parent_id
111
111
111
111
111
111
122
122
122
122
122
122
133
133
133
133
133
133
144
144
144
144
144
144
155
155
155
155
155
155
166
166
166
166
166
166


Problem je, da se posamezne vrstice duplicirajo 6-krat, ker jo v prvotnih tabeli 2 in tabeli 3 toliko vrstic.
Kako torej dosežem da se bodo vrstice duplicirale samo enkrat. Upam, da se bil dovolj jasen.

Sicer ne vem, če je to najboljši način za dupliciranje tabel.
Če pozna kdo kakšen boljši način, prosim, da ga napiše. Oprostite, če je vprašanje neumno vendar sem
brskal po netu in nisem naše rešitve problema.

Hvala,
Grega

tomi_m ::

Morda tole:

INSERT INTO table3(tid,mid,parent_id) SELECT DISTINCT t1.id, t2.id, t3.id FROM table1 AS t1, table2 AS t2, table3 AS t3

greentech ::

Ja v tem določene primeru bi to delovalo. Če pa so podatki drugačni recimo:

222333456
tid|mid|parent_id
12
13
14
14
15
16
16
16
16


DISTINCT upošteva podatke v vseh stolpcih v vrstici, torej če se nobena vrstica ne ponovi je ne izloči. Kako bi še lahko to rešil?

Hvala

borchi ::

in kaj bi ti rad videl v novi tabeli? kaj naj bi pomenilo "dupliciranje tabel"?
l'jga

greentech ::

Borchi, če poglledaš moj prvi post, boš videl da sme napisal kako izgledajo podatki v tabeli (table3) po izvedbi INSERT...SELECT stavka. V tabeli bi rad te podatke, vendar brez duplikatov. V primeru, da so podatki točno takšni kot sem jih napisal v začetnem postu lahko izločiš duplikate z uporabo DISTINCT.

V primeru, da se pa podatki v nobeni vrstici en duplicirajo pa uporaba DISTINCT ne deluje. V tem primeru se zgodi da se izpiše 6*6=36 vrstic, jaz bi pa rad da se jih samo 6, recimo vrstica

tid|mid|parent_id
126


izpiše samo enkrat ne pa šestkrat.

Upam, da sem zdaj dovolj jasno opisal moj problem.
Hvala,
Grega

borchi ::

INSERT
INTO table3(tid,mid,parent_id)
SELECT DISTINCT *
FROM (
SELECT DISTINCT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3
) as TAB
l'jga

greentech ::

Borchi, Hvala za pomoč in trud, vendar mi tvoj query še zmeraj vrne 36 vrstic namesto 6. Tokrat bom napisal točne podatke ,ki jih imam v tabelah (samo tiste, ki so tukaj pomembni)

Table1 (t1)

id
1


Table2 (t2)

id
1
2
3
4
5
6


Table3 (t3)

id
1
2
3
4
5
6


Tabela z rezultati naj bi zgledala tako:

tid|mid|parent_id|
111
122
133
144
155
166


Zgleda pa takole:

tid|mid|parent_id|
111
121
131
141
151
161
112
122
132
142
152
162
113
123
133
143
153
163
114
124
134
144
154
164
115
125
135
145
155
165
116
126
136
146
156
166


Torej, kot sem že napisal vsaka vrstica izpiše 6-krat namesto samo 1-krat. Vem da se najbrž že ponavljam, vendar upam da mi bo znal kdo pomagat. Hvala še enkrat, Grega

Zgodovina sprememb…

borchi ::

jaz ne vidim, da bi se ti kakšna vrstica podvojila. plus da je tisti moj dodatni distinct čisto nepotreben, samo nisem si prej vzel več kot 5 secund časa...

na relacijskih bazah boš pač dobil kartezični produkt (eksplozijo), če boš tiščal tri "neodvisne" tabele v eno. najprej se vprašaj kaj bi rad s to tabelo dobil, kakšne so relacije med temi tremi tabelami...

poleg tega imaš tudi na ta način dejansko tri tabele shranjene v eni.

ekvivalentni result set za t1:

select distinct tid
from skupna_tabela

za t2:

select distinct mid
from skupna_tabela

etc.

sicer se da nafilat tako tabelo kot jo želiš, samo kaj boš pa naredil, če imaš recimo v tabelah takole:

id
1

Table2 (t2)

id
1
2
3

Table3 (t3)

id
1
2
3
4
5
6

?
l'jga

ziga7 ::


INSERT INTO table3(tid,mid,parent_id)
SELECT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3
WHERE t2.id = t3.id

greentech ::

Hvala ziga7, sem msilil, da bo to prava rešitev pa na žalost ni. No delno je :)

Promlem nastane ker imam v table2 na začetku nekaj vrstic, ki imajo parent_id=NULL.
Teh vrstic ne želim duplirat. Recimo da je teh vrstic 6.
V tem primeru se table2.id začne z 7, table 3. id pa z 1

Uporabim ta stavek

INSERT INTO table3(tid,mid,parent_id)
SELECT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3
WHERE t2.parent_id IS NOT NULL AND t2.id = t3.id

Zaradi pogoja "t2.parent_id IS NOT NULL" pogoj "t2.id=t3.id" ni izpolnjen in se ne duplira nič.
Če izpustim pogoj "t2.parent_id IS NOT NULL" se duplirajo tudi podatki,
ki imajo t2.parent_id=NULL. Teh pa nočem duplirat.
Če pa ispustim pogoj "t2.id=t3.id" sem pa na istem kot prej.

Upam, da sem bil dovolj jasen.
Hvala še enkrat,
Grega

borchi ::

ok, naj me koklja brcne, če je tebe za razumet. šele zdele vidim, da insertiraš v Table3, ki ima tri kolone (tid,mid,parent_id), ko pa pokažeš design Table3 pa kažeš kot da ima eno (id) kolono...
l'jga

greentech ::

ja mogoče sem res bil malo nejasen.se opravičujem.
sicer sem pa napisal, da sem napisal samo podatke,
ki so pomembni, torej tiste, ki se duplicirajo v table3.
Da ima table3 3 kolone v katere se vstavlja je bilo pa
pa dobro razvidno iz INSERT stavka

borchi ::

no, in, ker ne povešt kaj pomeni dupliciranje tabel, kako naj bi zgledala Table3, če imaš:

Table1 (t1)

id
1

Table2 (t2)

id
1
2
3

Table3 (t3)

id
1
2
3
4
5
6
l'jga

ziga7 ::

Tisto s tabelo3 je bilo tudi nekam čudno, predvsem to, da bereš in vpisuješ v isto tabelo :|. Se mi pa zdi, da nas malo hecaš :)) tako da prosim, da še enkrat napišeš tabele tako kot dejansko so in predstaviš relacije med njimi. Iščeš rešitev za konkretno situacijo ali generično izjavo?

Po tvojem predzandjem odgovoru, mi je še malo manj jasno vse skupaj =>

table1.id
1

table2.id table2.parent_id
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
6 NULL
7
8
9
10
11
12

table3.id
1
2
3
4
5
6
------------------------------
ti pa bi rad po novem(?):
1 7 1
1 8 2
1 9 3
1 10 4
1 11 5
1 12 6
ja?

to je:

INSERT INTO table3(tid,mid,parent_id)
SELECT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3
WHERE t2.id = (t3.id+6)


samo to je samo za tvoj konkretni primer - ni generično. Prej je bilo nekaj logike - prej je brez podvajanja table2 in table3 vrnilo 6 vrstic - če sledimo tej logiki bi zdaj razumel, da hočeš 36 vrstic, vendar mi nekaj pravi, da jih vseeno hočeš samo 6 (moj nov query). O kartezičnem produktu je pa že borchi govoril. Seveda dopuščam možnost da ne razumem.

greentech ::

Oprosti moj namen ni bil nobenega hecat...je pa res da sem najbrž malo zakompliciral stvar.
OK, ne vem zakaj tega nisem naredil že prej. Bom dal konkreten tekst od naloge ki jo moram rešit, vključno z relacijami med tabelami, ker sem se preveč zapletel in drugače ne znam točno razložit kaj bi rad.

Naloga

In Ms SQL DB are three tables that related as shown on picture 1. We have the main table "template" sub table "tamplate_line" and sub - sub table "template_modules".

Picture 1:

 Tabele

Tabele



The object is to write a SQL procedure that would duplicate the complete tree structure of the 3 tables.

For illustration check table 2 with sample data. With yellow color are represented new table lines that were added by this duplicating SQL procedure.

First you will have to duplicate the one line in the "template" table. The field "name" in that duplicated line should have the value "duplicated page". Then you have to duplicate the data from the "Template_line" and "template_modules" table. Every time when you duplicate some data you must correctly fill the parent_id fields. The duplicated lines must have in the parent_id fields the ID of the source line. See example in table 2.

 table 2

table 2



Hvala obema še enkrat,
Grega

Zgodovina sprememb…

greentech ::

Ali mi lahko kdo pomaga?
Pa še eno vprašanje imam.
Kako bi dosegel, da se pri SELECT treh stolpcev DISTINCT upošteval samo na dveh.

To je delujoč SQL stavek:

SELECT DISTINCT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3

Jaz bi pa rad nekaj v smislu
SELECT t1.id, DISTINCT (t2.id, t3.id)
FROM table1 AS t1, table2 AS t2, table3 AS t3

kar seveda ne deluje. Kako bi lahko to rešil?

Hvala,
Grega

darkolord ::

Lahko narediš kakšen join, a nevem, če ma smisel, kar sprašuješ. Kaj točno bi rad naredil?

BlueRunner ::

To izgleda tako, kakor bi nekdo poskušal nekaj za denar na silo "programirati", pa ne pozna niti SQL, niti relacijskih baz. Še vprašanja so nejasna...

Sergio ::

:)

greentech: BlueRunner ima prav, za začetek si pa poglej GROUP BY clause, ki ponuja točno to, kar ti iščeš.
Tako grem jaz, tako gre vsak, kdor čuti cilj v daljavi:
če usoda ustavi mu korak,
on se ji zoperstavi.

greentech ::

Kaj točno bi rad naredil sem napisal dva posta višje. Tam je celotno besedilo naloge, ki jo moram rešit, skupaj z slikami.

V bistvu imam tale INSERT stavek:

INSERT INTO table3(tid,mid,parent_id) SELECT t1.id, t2.id, t3.id FROM table1 AS t1, table2 AS t2, table3 AS t3

Po izvedbi tega stavka so določene vreddnosti, če upoštevam samo tid in parent_id ali mid in tid podvojene.

Recimo:
tid|mid|parent_id|
841091291
841101291
841111291
841121291
841131291
841141291
841091292
841101292
841111292
841121292
841131292
841141292
841091293
841101293
841111293
841121293
841131293
841141293
841091294
841101294
841111294
841121294
841131294
841141294
841091295
841101295
841111295
841121295
841131295
841141295
841091296
841101296
841111296
841121296
841131296
841141296


Jaz bi pa rad tak rezultat:

tid|mid|parent_id|
841091291
841101292
841111293
841121294
841131295
841141296


Kako bi to dosegel?
Hvala, Grega

Zgodovina sprememb…

greentech ::

Hvala, Sergio. Sem si pogledal GROUP BY stavek.
Samo kolikor vidim, moraš v GROUP BY uporabiti vse stolpce, ki jih imaš v SELECT.

Torej tako:
SELECT t1.id, t2.id, t3.id
FROM table1 AS t1, table2 AS t2, table3 AS t3
GROUP BY t1.id, t2.id, t3.id

Če recimo GROUP BY uporabim samo t3.id mi javi napako.

WarpedGone ::

nad preostalimi stolpci - ki jih nimaš v Group By - moraš uporabit neko agregacijsko funkcijo, SUM, MIN, MAX, AVERAGE, ...
Zbogom in hvala za vse ribe

greentech ::

Ok z GROUP BY imam pa tudi problem.

Recimo da izvedem stavek:

INSERT INTO table3(tid,mid,parent_id) SELECT t1.id, MIN(t2.id), t3.id FROM table1 AS t1, table2 AS t2, table3 AS t3 GROUP BY t1.id, t3.id

Dobim rezultat:

tid|mid|parent_id|
841091291
841091292
841091293
841091294
841091295
841091296


Željen rezultat:

tid|mid|parent_id|
841091291
841101292
841111293
841121294
841131295
841141296


Bližje rešitvi je že, ni pa še čisto to kar iščem.
Hvala, Grega

borchi ::

1. gre za tri inserte
2. vrstni red insertov ni nepomemben, glede na to da imaš reference (foreign key-e) med tabelami
3. če si opazil moraš inkrementirati id-je. znaš inkrementirati "inline"?
4. če ne znaš, boš moral uporabit kurzor-je
5. še enkrat preberi kaj zahteva naloga;)
l'jga

borchi ::

rešitev one naloge zgoraj bi bila nekaj v tem stilu:

-- dupliciranje TEMPLATE
insert
into TEMPLATE
select count(*) + (select max(ID) from TEMPLATE) as NEW_ID
, t1.NAME
, t1.ID
from TEMPLATE t1
inner join TEMPLATE t2 on t1.ID >= t2.ID
where t1.PARENT_ID is null
group by t1.ID

-- dupliciranje TEMPLATE_MODULE
insert
into TEMPLATE_MODULE
select count(*) + (select max(ID) from TEMPLATE_MODULE) as NEW_ID
, t1.NAME
, t1.ID
from TEMPLATE_MODULE t1
inner join TEMPLATE_MODULE t2 on t1.ID >= t2.ID
where t1.PARENT_ID is null
group by t1.ID

-- dupliciranje povezovalne TEMPLATE_LINE
insert
into TEMPLATE_LINE
select (select max(ID) from TEMPLATE_LINE) + count(*) as NEW_ID
, t3.ID
, t4.ID
, t1.ID
from TEMPLATE_LINE t1
inner join TEMPLATE_LINE t2 on t1.ID >= t2.ID
inner join TEMPLATE t3 on t1.TID = t3.PARENT_ID
inner join TEMPLATE_MODULE t4 on t1.MID = t4.PARENT_ID
where t1.PARENT_ID is null
group by t1.ID


probaj.
l'jga

greentech ::

borchi deluje!
hvala ti ful!
grega


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Prosim vas za pomoč pri mysql queryju

Oddelek: Programiranje
131279 (1002) no comment
»

[SQL] - združitev glede na iste vrednosti

Oddelek: Programiranje
131268 (910) tx-z
»

MYSQL vprašanje

Oddelek: Programiranje
131666 (1281) MrBrdo
»

[Mysql]počasen rand in rešitve

Oddelek: Izdelava spletišč
131256 (1013) Tody
»

hierarhija, npr. kategorij

Oddelek: Izdelava spletišč
7869 (829) Zzzzzzz

Več podobnih tem