Vinnaren i pepparkakshustävlingen!
2015-12-21, 00:42
  #1
Moderator
Nospheratus avatar
Jag använder SQL Server 2014.

Kan man använda kolumner från en subquery i en selectsats? Äh, jag knåpar ihop ett usecase här istället, det blir lättare att förklara frågeställningen så istället.

Min tabell:

Kod:
ID         Namn                      Parent
1          Anders Andersson          2
2          Bengt Andersson           3
3          Claes Andersson           0

Tabellen blir som ett släktträd där varje person har en förälder. Kolumnen Parent pekar på kolumn ID för personens pappa. Gamle farfar Claes har ingen förälder så han får en nolla. För att ta reda på vem som är Anders Anderssons farfar måste jag med klassisk SQL ställa tre frågor:

Kod:
SELECT Parent FROM Tabell WHERE Namn="Anders Andersson"
(Svar: Parent = 2, Anders pappa har alltså ID=2 i tabellen)

SELECT Parent  FROM Tabell WHERE ID=2
(Svar: Parent = 3, Anders farfar har alltså ID=3 i tabellen)

SELECT Namn FROM Tabell WHERE ID=3
(Svar: Namn = Claes Andersson, Anders farfar heter alltså Claes Andersson) 

Fast nu vill jag vara fiffig och få ut namnen på både Anders, hans pappa och hans farfar i en och samma fråga. Jag lyckas hämta namnet på Anders och endast hans pappa så här:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa (Pappans namn)
FROM Tabell

Men hur fasiken ställer jag en subquery för Anders farfar med resultat från en första subquery med pappans förälder? Jag tänker mig så här, men det funkar inte:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa, (Pappans namn)
(SELECT Parent FROM Tabell WHERE ID=Tabell.Parent) AS FarfarsID, (Farfars ID i tabellen, den springade punkten så att säga)
(SELECT Namn FROM Tabell WHERE ID=FarfarsID) (Farfars namn)
FROM Tabell

Men det där funkar inte. SQL tycker inte att FarfarsID är en giltig kolumn i sista subqueryn. Och jag vet inte, det spelar som ingen roll hur jag försöker namnge de olika frågorna eller kolumnerna. Jag får inte till det. Jag är för kass på SQL. Är det ens möjligt att göra som jag tänker?
Citera
2015-12-21, 01:39
  #2
Medlem
brtkrbzhnvs avatar
Det kan göras med en subquery i en subquery, men det är bättre att göra något i stil med följande:
Kod:
SELECT T.Name, T_P.Name AS Parent, T_G.Name AS Grandparent
FROM Tabell T
LEFT JOIN Tabell T_P ON T_P.ID = T.Parent
LEFT JOIN Tabell T_G ON T_G.ID = T_P.Parent;
Otestad kod; kan ha syntaxfel och så vidare.
Citera
2015-12-21, 10:31
  #3
Moderator
Protons avatar
Citat:
Ursprungligen postat av brtkrbzhnv
Det kan göras med en subquery i en subquery, men det är bättre att göra något i stil med följande:
Kod:
SELECT T.Name, T_P.Name AS Parent, T_G.Name AS Grandparent
FROM Tabell T
LEFT JOIN Tabell T_P ON T_P.ID = T.Parent
LEFT JOIN Tabell T_G ON T_G.ID = T_P.Parent;
Otestad kod; kan ha syntaxfel och så vidare.
För förtydligandets skull kan vi alltså konstatera att det finns inget som hindrar att du, med hjälp av tabell-alias, joinar en tabell på sig själv i de antal led som krävs.
Citera
2016-01-15, 13:54
  #4
Medlem
Citat:
Ursprungligen postat av Nospheratu
Jag använder SQL Server 2014.

Kan man använda kolumner från en subquery i en selectsats? Äh, jag knåpar ihop ett usecase här istället, det blir lättare att förklara frågeställningen så istället.

Min tabell:

Kod:
ID         Namn                      Parent
1          Anders Andersson          2
2          Bengt Andersson           3
3          Claes Andersson           0

Tabellen blir som ett släktträd där varje person har en förälder. Kolumnen Parent pekar på kolumn ID för personens pappa. Gamle farfar Claes har ingen förälder så han får en nolla. För att ta reda på vem som är Anders Anderssons farfar måste jag med klassisk SQL ställa tre frågor:

Kod:
SELECT Parent FROM Tabell WHERE Namn="Anders Andersson"
(Svar: Parent = 2, Anders pappa har alltså ID=2 i tabellen)

SELECT Parent  FROM Tabell WHERE ID=2
(Svar: Parent = 3, Anders farfar har alltså ID=3 i tabellen)

SELECT Namn FROM Tabell WHERE ID=3
(Svar: Namn = Claes Andersson, Anders farfar heter alltså Claes Andersson) 

Fast nu vill jag vara fiffig och få ut namnen på både Anders, hans pappa och hans farfar i en och samma fråga. Jag lyckas hämta namnet på Anders och endast hans pappa så här:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa (Pappans namn)
FROM Tabell

Men hur fasiken ställer jag en subquery för Anders farfar med resultat från en första subquery med pappans förälder? Jag tänker mig så här, men det funkar inte:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa, (Pappans namn)
(SELECT Parent FROM Tabell WHERE ID=Tabell.Parent) AS FarfarsID, (Farfars ID i tabellen, den springade punkten så att säga)
(SELECT Namn FROM Tabell WHERE ID=FarfarsID) (Farfars namn)
FROM Tabell

Men det där funkar inte. SQL tycker inte att FarfarsID är en giltig kolumn i sista subqueryn. Och jag vet inte, det spelar som ingen roll hur jag försöker namnge de olika frågorna eller kolumnerna. Jag får inte till det. Jag är för kass på SQL. Är det ens möjligt att göra som jag tänker?
I Oracle finns en variant som letar reda på, så att säga, hela släktträdet. Det går att simulera CONNECT BY i SQL Server.
http://mindcurve.blogspot.se/2010/12...-by-prior.html
Citera
2016-01-25, 09:03
  #5
Medlem
Om du inte kräver topprestanda på insättning av data fungerar lösningen här bra: http://mikehillyer.com/articles/mana...data-in-mysql/
Citera
2016-01-25, 22:35
  #6
Medlem
Det finns ett "inbyggt släktträd" i SQL Server också, datatypen HierarchyId. Då måste du spara dem på rätt sätt sen kan du använda funktioner som t.ex. isDescendantOf.
Citera
2016-01-26, 12:49
  #7
Medlem
Citat:
Ursprungligen postat av poussard
Det finns ett "inbyggt släktträd" i SQL Server också, datatypen HierarchyId. Då måste du spara dem på rätt sätt sen kan du använda funktioner som t.ex. isDescendantOf.
Den verkar lite rigid på något sätt. Men hittade kanske inte rätt sidor på nätet.
Citera
2016-01-26, 22:39
  #8
Medlem
Citat:
Ursprungligen postat av SvenTuba
Den verkar lite rigid på något sätt. Men hittade kanske inte rätt sidor på nätet.

Kanske. Men om du vill få fram alla descendants med lösningen id och parentid får du använda en recursive cte vilket dels har sina begränsningar men också är lite bökigt. Det är väl en smaksak och olika lösningar är bra i olika sammanhang.
Citera
2016-02-18, 17:15
  #9
Medlem
Citat:
Ursprungligen postat av Nospheratu
Jag använder SQL Server 2014.

Kan man använda kolumner från en subquery i en selectsats? Äh, jag knåpar ihop ett usecase här istället, det blir lättare att förklara frågeställningen så istället.

Min tabell:

Kod:
ID         Namn                      Parent
1          Anders Andersson          2
2          Bengt Andersson           3
3          Claes Andersson           0

Tabellen blir som ett släktträd där varje person har en förälder. Kolumnen Parent pekar på kolumn ID för personens pappa. Gamle farfar Claes har ingen förälder så han får en nolla. För att ta reda på vem som är Anders Anderssons farfar måste jag med klassisk SQL ställa tre frågor:

Kod:
SELECT Parent FROM Tabell WHERE Namn="Anders Andersson"
(Svar: Parent = 2, Anders pappa har alltså ID=2 i tabellen)

SELECT Parent  FROM Tabell WHERE ID=2
(Svar: Parent = 3, Anders farfar har alltså ID=3 i tabellen)

SELECT Namn FROM Tabell WHERE ID=3
(Svar: Namn = Claes Andersson, Anders farfar heter alltså Claes Andersson) 

Fast nu vill jag vara fiffig och få ut namnen på både Anders, hans pappa och hans farfar i en och samma fråga. Jag lyckas hämta namnet på Anders och endast hans pappa så här:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa (Pappans namn)
FROM Tabell

Men hur fasiken ställer jag en subquery för Anders farfar med resultat från en första subquery med pappans förälder? Jag tänker mig så här, men det funkar inte:

SELECT Namn,
Tabell.Parent,
(SELECT Namn FROM Tabell WHERE ID=Tabell.Parent) AS Pappa, (Pappans namn)
(SELECT Parent FROM Tabell WHERE ID=Tabell.Parent) AS FarfarsID, (Farfars ID i tabellen, den springade punkten så att säga)
(SELECT Namn FROM Tabell WHERE ID=FarfarsID) (Farfars namn)
FROM Tabell

Men det där funkar inte. SQL tycker inte att FarfarsID är en giltig kolumn i sista subqueryn. Och jag vet inte, det spelar som ingen roll hur jag försöker namnge de olika frågorna eller kolumnerna. Jag får inte till det. Jag är för kass på SQL. Är det ens möjligt att göra som jag tänker?

Har du provat köra en unique och sedan en string från första till sista bokstav av första namnet? Allt beror på hur stor datasetet blir.

Jag vet inte riktigt vad är ändamålet är eller om du ska använda det här datat i andra datset, men du kan prova dumpa datat in i ett temporär INTO # eller en ren INTO tabell och från den kan du vidarebearbeta ditt data.

Baserad på det du har presenterad, jag skulle köra en string från första bostav till sista bostav i förnamnet.

Jag ser att hela namnet är " förnamn efternamn". Varför inte skapa en till kolumn så du har "namn" och den nya kolumnen,som kan heta "Efternamn".

Har du tittat på IsDescendantOf ? Jag har använt den på jobbet och fungerat bra för små saker. Inte så komplicerad att använda.

Lycka till!
Citera
2016-02-28, 10:44
  #10
Medlem
Googla på CTE. Mha av en sådan skapar du enkelt en rekursiv fråga.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback