Avatar billede pepsdk Nybegynder
15. januar 2008 - 13:37 Der er 17 kommentarer

Opdatering af udvalgte data baseret på et select

Hejsa,

Jeg har en GRUND_TABEL indeholdende en masse informationer. Heriblandt nogle unikke id´s og datoer.

Jeg afvikler noget SQL for at udtrække de datoer som kan slås sammen. Ud fra dette får jeg en tabel indeholdende 2 IDér, ex:

ID1, ID2
xxx, yyy
aaa, bbb

Dette SQL udtræk har jeg lagt over i et view.


Nu skal jeg så løbe igennem min GRUND_TABEL og for hver, som matcher ID1 skal jeg sætte ID1´s DATO = ID2´s Dato.

Dette skal naturligvis køres for alle rækker i mit view.

Skriv endelig hvis i ikke forstår problemstillingen!
Avatar billede the_party_dog Nybegynder
15. januar 2008 - 14:15 #1
UPDATE GRUND_TABEL
SET GRUND_TABEL.DATO = VIEW.DATO
WHERE GRUND_TABEL.ID1 = VIEW.ID1

Lidt uklart formuleret, så jeg forventer det er dette du ønsker at opnå? Ellers må du jo lige skrive lidt mere og vise noget mere data så vi kan løse det for dig :o)
Avatar billede pepsdk Nybegynder
15. januar 2008 - 14:26 #2
hmm er svært at forklare, hehe.

skulle gerne være noget ala:

UPDATE GRUND_TABEL
SET GRUNDTABEL.TIlDATO = TILDATO (hvor jeg skal finde TILDATOEN ud fra det unikke ID i GRUNDTABEL = ID2, altså der skal ske en form for opslag.. hvilket skal ske for alle rækker i mit view)
WHERE (det unikke id i GRUNDTABEL) = ID1
Avatar billede the_party_dog Nybegynder
15. januar 2008 - 14:40 #3
Kan du skrive noget konkret data op, bare lige 2 linjer med ID og dato, vise hvordan resultatet skal se ud efter din update? Det ville gøre det hele lidt mere synligt...
Avatar billede pepsdk Nybegynder
15. januar 2008 - 14:50 #4
GRUND_TABEL:

UNIKT_ID, FRADATO                  TILDATO
-----------------------------------------------------------
1        1991-01-31 00:00:00.000  2001-01-30 00:00:00.000
2        2001-01-31 00:00:00.000  2002-01-31 00:00:00.000

Ud fra dette har jeg lavet noget sql, som jeg har smidt ind i et view.

Det sql sammenligner perioderne og finder nogle som kan slås sammen. I mit view har jeg altså stående:

START_ID, SLUT_ID
-----------------
1        2

Nu vil jeg så gerne have opdateret min GRUND_TABEL så den ser ud som følger:

UNIKT_ID, FRADATO                  TILDATO
-----------------------------------------------------------
1        1991-01-31 00:00:00.000  2002-01-31 00:00:00.000

Slut datoen fra ID 2 er blevet sat ind istedet for ID1´s og ID2 er slettet.

Håber det giver mere mening.
Avatar billede pepsdk Nybegynder
15. januar 2008 - 14:53 #5
og der kan altså være flere rækker i mit view, hvorfor der skal itereres på en eller anden måde :)
Avatar billede pepsdk Nybegynder
15. januar 2008 - 15:13 #6
P.t er jeg ude i noget ala:

UPDATE GRUND_TABEL
SET GRUND_TABEL.TIL = (SELECT TIL FROM GRUND_TABEL WHERE ID = view.ID2)
FROM VIEW
INNER JOIN GRUND_TABEL
ON view.ID1 = GRUND_TABEL.ID
WHERE ID = VIEW.ID1
Avatar billede the_party_dog Nybegynder
15. januar 2008 - 15:26 #7
UPDATE GRUND_TABEL
SET GRUND_TABEL.Tildato = G2.Tildato
INNER JOIN VIEW AS V1 ON view.ID1 = GRUND_TABEL.ID INNER JOIN GRUND_TABEL AS G2 ON V1.ID1 = G2.ID
WHERE ID = VIEW.ID1

Det vi ønsker at opnå er at du laver en self join mod din grundtabel. Fordi du har et view som indeholder ID'et på den række der skal opdateres og ID'et med den række vi skal hente fra, så skal du lave 2 joins. Et join til at finde rækken der skal ændres (hvor din where sætning slår igennem) og et til at finde den række hvor du vil hente til datoen.

Lidt svært finde runde i dine navne på dine kolonner, prøv at kalde dem hvad de hedder i virkeligheden eller kald dem det samme hele vejen igennem dine eksempler :o)
Avatar billede the_party_dog Nybegynder
15. januar 2008 - 15:44 #8
Testet med de navne du har oplyst klokken 14:50:56:

UPDATE dbo.GRUND_TABEL

SET dbo.GRUND_TABEL.TILDATO = G2.TILDATO
FROM dbo.[VIEW] AS V INNER JOIN dbo.GRUND_TABEL ON V.START_ID = dbo.GRUND_TABEL.UNIKT_ID INNER JOIN dbo.GRUND_TABEL AS G2 ON G2.UNIKT_ID = V.SLUT_ID
WHERE dbo.GRUND_TABEL.UNIKT_ID = V.START_ID
Avatar billede pepsdk Nybegynder
15. januar 2008 - 15:52 #9
Ok, tror jeg har fået UPDATE delen til at virke. SÅ kommer næste problem.

Nu skal den "unødvendige" record slettes. Men hvordan finder jeg frem til den, når mit view er blevet opdateret (tomt) efter min update.

Jeg kan altså ikke lave en DELETE FROM GRUND_TABEL where ID in (SELECT ID2 from VIEW)

Er det muligt at køre både UPDATE/DELETE statement i en form for transaction, så mit view ikke bliver opdateret inden jeg når til mit DELETE statement.?
Avatar billede the_party_dog Nybegynder
15. januar 2008 - 16:55 #10
Jeg synes lige du skal se om dette kan give dig id'er på de dubletter du vil slette, ellers skal du bare vende < tegnet til > og se om det giver det rigtige. Hvis ja, så bruger det bare det som en subquery til en delete statement...

SELECT G1.UNIKT_ID
FROM dbo.GRUND_TABEL AS G1 INNER JOIN dbo.GRUND_TABEL AS G2 ON G1.TILDATO = G2.TILDATO
WHERE DATEDIFF(dd, G1.FRADATO, G1.TILDATO) < DATEDIFF(dd, G2.FRADATO, G2.TILDATO)

DELETE dbo.GRUND_TABEL
WHERE UNIKT_ID IN (
SELECT DISTINCT G1.UNIKT_ID
FROM dbo.GRUND_TABEL AS G1 INNER JOIN dbo.GRUND_TABEL AS G2 ON G1.TILDATO = G2.TILDATO
WHERE DATEDIFF(dd, G1.FRADATO, G1.TILDATO) < DATEDIFF(dd, G2.FRADATO, G2.TILDATO))
Avatar billede pepsdk Nybegynder
15. januar 2008 - 17:04 #11
Okay jeg kigger lige på det imorgen og vender tilbage. Tak for hjælpen indtil videre!
Avatar billede pepsdk Nybegynder
16. januar 2008 - 08:33 #12
Umiddelbart giver det mig ikke det rigtige, da der kan være mange rækker med samme tildato. Jeg har overvejet om en TEMP tabel med indholdet (de 2 I´s) er vejen frem og så trunkere denne pr. gennemløb, men jeg er lidt bange for det overhead det vil give.
Avatar billede the_party_dog Nybegynder
16. januar 2008 - 08:58 #13
Du kan lave det hele med en foreach der løber det hele igennem og laver en tabel med de id'er du gerne vil have eller slette dem direkte.

Hvor mange rækker snakker vi om?
Avatar billede pepsdk Nybegynder
16. januar 2008 - 09:00 #14
Hvordan ser sådan en foreach ud i SQL?

P.t. arbejder jeg med en WHILE løkke som tester om: Count(*) from view > 0.

Den største tabel jeg løber igennem har p.t. 3 millioner rækker.
Avatar billede the_party_dog Nybegynder
16. januar 2008 - 10:40 #15
Du kan slå det op i Books Online, der vil du se et lille eksempel på hvordan man laver en foreach...
Avatar billede pepsdk Nybegynder
16. januar 2008 - 11:10 #16
Kunne du måske smide et link? Jeg kan ikke selv finde det.
Avatar billede the_party_dog Nybegynder
16. januar 2008 - 11:41 #17
Min fejl :o) Det var en fetch jeg mente, hvilket du nok har prøvet dig lidt frem med... http://technet.microsoft.com/en-us/library/ms180152.aspx

Men hvis du gerne vil have gang i noget Foreach lignende fra C#, så kan du jo lave en Stored Procedure skrevet i C#...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester