Trädvy Permalänk
Medlem
Registrerad
Nov 2011

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

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

Trädvy Permalänk
Medlem
Plats
Skara
Registrerad
Jul 2005

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

...

Trädvy Permalänk
Medlem
Registrerad
Nov 2011
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?

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

Trädvy Permalänk
Medlem
Registrerad
Mar 2012

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;

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

Trädvy Permalänk
Avstängd
Registrerad
Jun 2016

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...

Trädvy Permalänk
Medlem
Registrerad
Nov 2011
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!

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

Trädvy Permalänk
Medlem
Registrerad
Mar 2012

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

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

Trädvy Permalänk
Medlem
Registrerad
Nov 2011
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?

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

Trädvy Permalänk
Medlem
Registrerad
Mar 2012

@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.

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

Trädvy Permalänk
Medlem
Registrerad
Nov 2011
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!

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

Trädvy Permalänk
Medlem
Plats
Härnösand
Registrerad
Jan 2016

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;