Permalänk
Medlem

Avancerad SQL fråga

Hallå!

Jag har en tabell i en databas som vi kallar shapes. I denna finns det fält med shape_id och child_shape_id.

Jag ställer en fråga för att hämta ut alla rader för ett shape_id och använder mig sedan utav child_shape_id för att hämta dess child_shape_ids osv. Så det blir en rekursiv hämtningsprocess. Detta utspelar sig även på andra tabeller i databasen och gör att resultatet tar en cirka 6 sekunder att få fram. Så jag undrar om någon vet ifall det finns något sätt att hämta ut allt som är relevant redan i usprungsfrågan utan att behöva göra det med rekursion då jag inbillar mig att SQL är snabbare(?) än vad min rekursion kan hantera och sänker tidskomplexiteten.

Fråga gärna om något är oklart så ska jag göra mitt bästa för att förska förklara på något annat sätt.

Tack på förhand
Mvh

Visa signatur

Crosshair IV | 1055T @ 3.2 GHz | 4 GB Corsair dominator | Corsair H50 | Fractal Design R3 | 2x PowerColor 6950 2GB | Corsair HX 750W

Permalänk
Medlem

Du får köra med JOIN, antingen direkt i din SQL, eller t.ex. via LINQ.

Visa signatur

...

Permalänk
Medlem
Skrivet av Hal0:

Du får köra med JOIN, antingen direkt i din SQL, eller t.ex. via LINQ.

Går det att joina med resultatet som jag får från den första queryn?

Visa signatur

Crosshair IV | 1055T @ 3.2 GHz | 4 GB Corsair dominator | Corsair H50 | Fractal Design R3 | 2x PowerColor 6950 2GB | Corsair HX 750W

Permalänk
Medlem

Join är ingen vidare idé såvida han inte vet exakt hur många nivåer med children det kan finnas. Det här är snarare exakt det common table expressions är till för (iaf i MS SQL, det framgick inte vad du använde).

Här är lite att börja med (helt otestat).

declare @shape_id int; ;WITH CTE(shape_id, child_shape_id) AS ( SELECT shape_id, child_shape_id FROM shapes WHERE shape_id = @shape_id UNION ALL SELECT shape_id, child_shape_id FROM CTE INNER JOIN shapes AS S ON CTE.child_shape_id = S.shape_id ) SELECT S.* FROM CTE INNER JOIN shapes AS S ON CTE.shape_id = S.shape_id;

Visa signatur

Asus X99-A, Intel i7 5820K, 16GB DDR4, GTX 980 SLI, Asus PG278QR + Asus VG274H

Permalänk
Avstängd

Du nämnde inte vilken databashanterare det är men SQL Server har något som heter Common Table Expressions (CTE) som kan göra rekursion.

https://technet.microsoft.com/en-us/library/ms190766(v=sql.10...

Permalänk
Medlem
Skrivet av sime:

Join är ingen vidare idé såvida han inte vet exakt hur många nivåer med children det kan finnas. Det här är snarare exakt det common table expressions är till för (iaf i MS SQL, det framgick inte vad du använde).

Här är lite att börja med (helt otestat).

declare @shape_id int; ;WITH CTE(shape_id, child_shape_id) AS ( SELECT shape_id, child_shape_id FROM shapes WHERE shape_id = @shape_id UNION ALL SELECT shape_id, child_shape_id FROM CTE INNER JOIN shapes AS S ON CTE.child_shape_id = S.shape_id ) SELECT S.* FROM CTE INNER JOIN shapes AS S ON CTE.shape_id = S.shape_id;

Skrivet av cavange:

Du nämnde inte vilken databashanterare det är men SQL Server har något som heter Common Table Expressions (CTE) som kan göra rekursion.

https://technet.microsoft.com/en-us/library/ms190766(v=sql.10...

Det är oracles som används. Får kika om CTE finns för den. Jag vet inte hur många barn som finns. Tack!

Visa signatur

Crosshair IV | 1055T @ 3.2 GHz | 4 GB Corsair dominator | Corsair H50 | Fractal Design R3 | 2x PowerColor 6950 2GB | Corsair HX 750W

Permalänk
Medlem

@Dalgren: Om jag inte minns fel heter det Hierarchical Queries i Oracle, tyvärr kan jag inte den syntaxen i huvudet! Lycka till.

Visa signatur

Asus X99-A, Intel i7 5820K, 16GB DDR4, GTX 980 SLI, Asus PG278QR + Asus VG274H

Permalänk
Medlem
Skrivet av sime:

@Dalgren: Om jag inte minns fel heter det Hierarchical Queries i Oracle, tyvärr kan jag inte den syntaxen i huvudet! Lycka till.

Tack så mycket! Det ser lovande ut. Vet du om detta är "snabbare" än att göra det rekursivt i PHP?

Visa signatur

Crosshair IV | 1055T @ 3.2 GHz | 4 GB Corsair dominator | Corsair H50 | Fractal Design R3 | 2x PowerColor 6950 2GB | Corsair HX 750W

Permalänk
Medlem

@Dalgren: Om jag får gissa, så mellan 100-1000 ggr snabbare, det ska inte ta många ms att köra en sådan fråga.

Visa signatur

Asus X99-A, Intel i7 5820K, 16GB DDR4, GTX 980 SLI, Asus PG278QR + Asus VG274H

Permalänk
Medlem
Skrivet av sime:

@Dalgren: Om jag får gissa, så mellan 100-1000 ggr snabbare, det ska inte ta många ms att köra en sådan fråga.

Najs! Då kanske chefen blir glad!

Visa signatur

Crosshair IV | 1055T @ 3.2 GHz | 4 GB Corsair dominator | Corsair H50 | Fractal Design R3 | 2x PowerColor 6950 2GB | Corsair HX 750W

Permalänk
Medlem

Kör med INNER JOINE Joine och LEFT sedan kör värde typ

a.id, b.uid, c.userid

Beror på hur många tabeller du ska köra i en och samma SQL fråga.

JOINE Syntex
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;

eller

SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;

med left JOINE så kör du

SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

eller

SELECT column_name(s)
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name=table2.column_name;