Jag har i ett databasprojekt sökt igenom en webbplats och fran denna hämtat information som nu är lagrad i en tabell data med följade struktur:
-------------------------------------
| table | id | type | value |
-------------------------------------
| dvd | 01 | title | Finding Nemo |
| dvd | 01 | price | 9.99 |
| dvd | 01 | genre | Disney |
| dvd | 02 | title | Gladiator |
| dvd | 02 | price | 10.99 |
etc |
-------------------------------------
Vad som ska ske är att innehallet i data ska föras över till den tabell som anges i fältet table. I mitt fall är det dock bara maltabellen "dvd" som är aktuell. En förenklad struktur av dvd är som följer:
| id | title | price | genre |
data ska alltsa föras över via följande tva rader:
| 01 | Finding Nemo | 9.99 | Disney |
| 02 | Gladiator | 9.99 | NULL |
(Gladiator har alltsa ingen angiven genre.)
Nagra tips pa hur detta görs enklast? Det är framför allt den inledande SQL-fragan jag funderar pa; är det smartast att göra en simpel SELECT DISTINCT(id) och sedan loopa fram information för varje film i ett Java-program, eller har ni nagra bättre förslag (GROUP BY kanske)?
Antingen hämtar du all data och loopar igenom i ett program och gör en INSERT för varje rad, som du själv föreslår.
Eller så gör du loopningen i SPn med cursors.
Alternativ tre skulle vara att göra en INSERT och för varje värde som ska in gör man en SELECT på id. Men jag har ingen testad kod för detta just nu.
Oj, här snackas det nya grejor :). Vad innebär en "loopning i SPn med cursors"?
För att spinna vidare pa mitt egna förslag kan jag precisera vari min fraga ligger:
SELECT DISTINCT(id) FROM data
loop
INSERT INTO dvd (id, title, price, genre) VALUES [b][red]vad kommer här?[/red][/b]
end loop
Kan jag (1) lägga flera SELECT-satser i INSERT-satsen, eller (2) maste jag först plocka ut önskade värden via separata SELECT-satser? Nagot slags exempel ($ indikerar variabel):
1.
INSERT INTO dvd (id, title, price, genre) VALUES ($id, (SELECT title FROM data WHERE id = $id), (SELECT price FROM data WHERE id = $id) ...)
2.
$title = SELECT title FROM data WHERE id = $id
...
INSERT INTO dvd (...) VALUES ($id, $title, ...)
Nagra tips pa hur detta görs enklast? Det är framför allt den inledande SQL-fragan jag funderar pa; är det smartast att göra en simpel SELECT DISTINCT(id) och sedan loopa fram information för varje film i ett Java-program, eller har ni nagra bättre förslag (GROUP BY kanske)?
Jag hajar inte riktigt vad du vill göra. Du vill alltså hämta unika poster (id) från en tabell och lagra dem i en ny tabell med ett annat utseende? Du behöver också hämta fler kolumner från tabellen än id? Vilken databashanterare använder du?
PS.
Distinct är ingen funktion och ska skrivas "distinct id", utan paranterser.
insert into dvd
select distinct id,
(select value from data where type = 'title' and id = d.id),
(select cast(value as decimal(10,2)) from data where type = 'price' and id = d.id),
(select value from data where type = 'genre' and id = d.id)
from data as d
Du kanske måste lägga till någon ytterligare cast för t.ex. id.
K@llen: Precis. Later förmodligen ganska onödigt, men själva överföringen av data mellan de tva tabellerna är en del av projektet. Tack för papekandet om distinct.
LarsG: Det där ser väldigt lovande ut. Ska testas bums i morgon :).
Det var lite oklart om det fanns med data för andra tabeller än dvd. I så fall kan du lägga på det villkoret.
insert into dvd
select distinct id,
(select value from data where type = 'title' and id = d.id
and table = 'dvd'),
(select cast(value as decimal(10,2)) from data where type = 'price' and id = d.id and table = 'dvd'),
(select value from data where type = 'genre' and id = d.id and table = 'dvd')
from data as d
where table = 'dvd'
(table är inget bra kolumnnamn.)
Om du fortfarande får flera poster så kanske det hjälper med att lägga till distinct i subselect.
select distinct value
Om det fortfarande inte hjälper så har du nog lite problem med ditt indata efetrsom det finns motstridiga uppgifter.
Grr, far det fortfarande inte att fungera. För att lättare kunna se felet gjorde jag en tabell Data_Test med följande struktur och innehall (de horisontala strecken är bara där för att tydliggöra innehallet):
--------------------------------
| id | type | value |
--------------------------------
| 111 | title | First title |
| 111 | genre | First genre |
| 111 | seller | First seller |
--------------------------------
| 222 | title | Second title |
| 222 | genre | Second genre |
| 222 | seller | Second seller |
--------------------------------
| 333 | title | Third title |
| 333 | genre | Third genre |
| 333 | seller | Third seller |
--------------------------------
Mitt mal är nu att med följande kod lyckas skapa tre rader i tabellen Dvd:
insert into dvd
select distinct id,
(select value from data_test where type = 'title' and id = d.id),
(select value from data_test where type = 'genre' and id = d.id),
(select value from data_test where type = 'seller' and id = d.id)
from data_test as d;
Glad i hagen trodde jag att nu MASTE det vara rätt. Men ... Resultatet blir tre identiska rader för varje ID :(. Att lägga in DISTINCT även för title, genre och seller gav inget, och verkar i detta fall hellre inte sa logiskt.
Kan det vara Pointbase, min DBMS, som inte klarar av den här typen av SQL-fragor?
Utan dubletter aterkommer jag dock till problemet som beskrivs ovan, da jag använder Data_Test -- trots DISTINCT-attributet försöker Pointbase skapa en rad i Dvd för varje attribut som matchar aktuellt id.
Output för Data_Test ovan blir alltsa
-----------------------------------------------------
| id | title | genre | seller |
-----------------------------------------------------
| 111 | First title | First genre | First seller |
| 111 | First title | First genre | First seller |
| 111 | First title | First genre | First seller |
-----------------------------------------------------
| 222 | Second title | Second genre | Second seller |
| 222 | Second title | Second genre | Second seller |
| 222 | Second title | Second genre | Second seller |
-----------------------------------------------------
| 333 | Third title | Third genre | Third seller |
| 333 | Third title | Third genre | Third seller |
| 333 | Third title | Third genre | Third seller |
-----------------------------------------------------
Den outputen utan dublettrader och allt skulle vara frid och fröjd ...
CREATE VIEW DvdView AS
select distinct id,
(select value from data_test where type = 'title' and id = d.id),
(select value from data_test where type = 'genre' and id = d.id),
(select value from data_test where type = 'seller' and id = d.id)
from data_test as d;
INSERT INTO Dvd
select distinct * from DvdView;
Behövdes bara lite tid för eftertanke :). Tack LarsG för hjälpen!
282 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e