Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Mar 2003

SQL fråga

Håller på med en SQL-fråga jag inte riktigt får till.

Har några kolumner

[id] [namn] [stad]

Det jag vill att jag vill få fram om jag söker ut

where stad='stockholm'

då får jag alla namn tex kalle, nisse tex som är sorterad under stockholm.
MEN om jag också vill visa ALLA kalle, nisse också oavsett stad.

Det jag vill är alltså att få fram en lista med namn först på stad, sedan komplettera listan med alla namnen oavsett stad.
Tex om jag hade en kalle i göteborg också ska det visa

[id] [namn] [stad]
1 kalle stockholm
2 nisse stockholm
3 kalle göteborg

Alltså en SQL fråga i en annan fråga beroende på vilka namn jag får fram..

K#

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007

select * from tabell where stad = 'stockholm' union all select * from tabell where stad <> 'stockholm'

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Jan 2004

Fuling :

select * from tabell where stad = "stockholm" UNION select * from tabell where stad != "stockholm"

Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Mar 2003
Skrivet av iXam:

Fuling :

select * from tabell where stad = "stockholm" UNION select * from tabell where stad != "stockholm"

Har inte pillat med union alls... tyvärr..

Men det jag får fram är ju i första läget rätt, allt från stockholm.
MEN, i andra läget får jag ju även fram resten av tabellen..

Utrifrån vilka namn jag får i första frågan, jag vill ta listan med namn i stockholm. Visa alla namnen som är kopplat till stockholm, men även dubliceringar av namn som inte är kopplat till stockholm.

tar jag alla namnen som inte är kopplat till stockholm får jag ju allt med.

Tex.
Nisse Stockholm
Frasse Stockholm

Nisse Göteborg
Kalle Göteborg

Frasse Alingsås

Om min databas innehöll ovan info, då ska jag INTE se Kalle i Göteborg, för att han finns inte med i stockolmslistan..

Hoppas jag uttrycker mig hyfsat vad jag är ute efter.

K#

Trädvy Permalänk
Medlem
Plats
Stockholms immigrant
Registrerad
Aug 2005

Ifall det är sql server så kolla på rekursiv cte.
Annars kan du skapa en tempvariabel och ladda in från första frågan och sen använda det som filter till nästa.

Trädvy Permalänk
Medlem
Registrerad
Apr 2006

Testa nåt i stil med detta:
SELECT * FROM `tabell` WHERE `stad` = 'stockholm'
UNION
SELECT * FROM `tabell` WHERE `namn` IN (SELECT `namn` FROM `test` WHERE `stad` = 'stockholm') AND `stad` != 'stockholm'

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Feb 2002

Jag tycker du får göra en subquery som hämtar ut namnen på alla som bor i Stockholm. Sedan använder du den listat till att välja ut samtliga personer som har något av Stockholmsnamnen.

Så här kan det se ut:

@X TABLE ( ID int PRIMARY KEY CLUSTERED, Namn varchar(30), Stad varchar(30) ) INSERT @X (ID, Namn, Stad) VALUES (1, 'Kalle', 'Stockholm') INSERT @X (ID, Namn, Stad) VALUES (2, 'Nisse', 'Stockholm') INSERT @X (ID, Namn, Stad) VALUES (3, 'Kalle', 'Göteborg') INSERT @X (ID, Namn, Stad) VALUES (4, 'Anna', 'Göteborg') INSERT @X (ID, Namn, Stad) VALUES (5, 'Frasse', 'Alingsås') INSERT @X (ID, Namn, Stad) VALUES (6, 'Eva', 'Alingsås') INSERT @X (ID, Namn, Stad) VALUES (7, 'Nisse', 'Alingsås') SELECT ID, Namn, Stad FROM @X WHERE Namn IN (SELECT DISTINCT(Namn) FROM @X WHERE Stad = 'Stockholm')

/Johan

Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Mar 2003
Skrivet av Wiinis:

Ifall det är sql server så kolla på rekursiv cte.
Annars kan du skapa en tempvariabel och ladda in från första frågan och sen använda det som filter till nästa.

Var inne på en tvåstegsraket men jag är så begränsad på SQL att jag läste in första frågan en datatable i C# och utifrån det hämta rätt data från SQL:en igen.

Skrivet av protovaffe:

Testa nåt i stil med detta:
SELECT * FROM `tabell` WHERE `stad` = 'stockholm'
UNION
SELECT * FROM `tabell` WHERE `namn` IN (SELECT `namn` FROM `test` WHERE `stad` = 'stockholm') AND `stad` != 'stockholm'

Testade din variant och den funkar fint!, precis som jag tänkt mig.
Nu kommer mina lagerarbetare bli glada (en metod för att hitta lagerplats där viss sorts varor har ställts tidigare utifrån en fritextdata)

K#

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2006

Testa, borde vara snabbare och lite tydligare.

Select t2.* From tabellnamn as t1 left join tabellnamn as t2 on t1.namn = t2.namn where t1.stad like 'stockholm'

Notera att tabellnamn är din tabell och samma tabell används 2ggr och kallas i ena tillfället t1 och andra tillfället för t2.

INTEL CORE I7 3930K 3.20GHZ 12MB S-2011, FRACTAL DESIGN MIDITOWER DEFINE R3, CORSAIR HX 1050W, ASUS RAMPAGE IV FORMULA, Asus STRIX GTX970, CORSAIR 16GB DDR3 DOMINATOR QUAD 1866MHZ CL9 (4X4GB) Ljud: ASUS Xonar D2X/XDT 7.1 | Elac 5.1 +förstärkare | Cambridge dacmagic plus | Astro gaming A40 | Sennheiser HD 650
You ask me if I have a god complex? Let me tell you something, I am god!

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Maj 2009
Skrivet av IceDread:

Testa, borde vara snabbare och lite tydligare.

Select t2.* From tabellnamn as t1 left join tabellnamn as t2 on t1.namn = t2.namn where t1.stad like 'stockholm'

Notera att tabellnamn är din tabell och samma tabell används 2ggr och kallas i ena tillfället t1 och andra tillfället för t2.

OP: du borde använda denna istället för att köra en select 3 gånger

Min dator: Silent Base 600 | 1700X @ 3.9Ghz | MSI Gaming X 1080TI | RM750X | 512Gb M2 | 16Gb 3200mhz Ram | S34E790C @ 3440x1440
Tjejens dator: Define r4 | i5 3570k @ 4.2ghz | GTX Titan | 750w Supernova | 240gb SSD | 32gb ram
Citera/Tagga för svar!

Trädvy Permalänk
Medlem
Registrerad
Dec 2013

Jag kanske missförstår frågan, men varför inte bara lägga till en "order by stad, namn" så kommer den sortera efter stad först och namn sen?

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Maj 2009
Skrivet av smurfb:

Jag kanske missförstår frågan, men varför inte bara lägga till en "order by stad, namn" så kommer den sortera efter stad först och namn sen?

för då får han inte ut namnen från en annan stad

Min dator: Silent Base 600 | 1700X @ 3.9Ghz | MSI Gaming X 1080TI | RM750X | 512Gb M2 | 16Gb 3200mhz Ram | S34E790C @ 3440x1440
Tjejens dator: Define r4 | i5 3570k @ 4.2ghz | GTX Titan | 750w Supernova | 240gb SSD | 32gb ram
Citera/Tagga för svar!

Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Mar 2003
Skrivet av IceDread:

Testa, borde vara snabbare och lite tydligare.

Select t2.* From tabellnamn as t1 left join tabellnamn as t2 on t1.namn = t2.namn where t1.stad like 'stockholm'

Notera att tabellnamn är din tabell och samma tabell används 2ggr och kallas i ena tillfället t1 och andra tillfället för t2.

Perfekt!

Tack så mycket, alltid trevligt att kunna snabba upp frågorna för servern och användarna.

K#

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Feb 2005
Skrivet av IceDread:

Testa, borde vara snabbare och lite tydligare.

Select t2.* From tabellnamn as t1 left join tabellnamn as t2 on t1.namn = t2.namn where t1.stad like 'stockholm'

Notera att tabellnamn är din tabell och samma tabell används 2ggr och kallas i ena tillfället t1 och andra tillfället för t2.

Fast det ger ju inte vad OP vill ha.

Resultatet blir fel (bara att testa när det finns mer än en person från en stad med samma namn.)

Resultatet presenteras inte heller korrekt, dvs först alla namn från staden X och sedan alla från alla andra städer med samma namn som de namn som finns i staden X.
Snabbare är det heller inte, tvärtom.

Det här ger resultatet formaterat som OP vill ha:

SELECT * FROM table WHERE stad = "Stockholm" UNION ALL SELECT * FROM table WHERE namn IN (SELECT namn FROM table WHERE stad = "Stockholm") AND stad <> "Stockholm"

Alla från den utvalda staden kommer först, efter det kommer alla från alla andra städer med samma namn som de i staden man sökt på.

Vilket är vad @protovaffe föreslog ovanför förutom då att jag använder UNION ALL för att presentera resultatet så som OP ville ha det.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2006
Skrivet av Gropenator:

Fast det ger ju inte vad OP vill ha.

Resultatet blir fel (bara att testa när det finns mer än en person från en stad med samma namn.)

Resultatet presenteras inte heller korrekt, dvs först alla namn från staden X och sedan alla från alla andra städer med samma namn som de namn som finns i staden X.
Snabbare är det heller inte, tvärtom.

Det här ger resultatet formaterat som OP vill ha:

SELECT * FROM table WHERE stad = "Stockholm" UNION ALL SELECT * FROM table WHERE namn IN (SELECT namn FROM table WHERE stad = "Stockholm") AND stad <> "Stockholm"

Alla från den utvalda staden kommer först, efter det kommer alla från alla andra städer med samma namn som de i staden man sökt på.

Vilket är vad @protovaffe föreslog ovanför förutom då att jag använder UNION ALL för att presentera resultatet så som OP ville ha det.

Sant, glömde ta med group by, lägg på en group by t2.Id, t2.Namn, t2.Stad på slutet så blir det fint.

select t2.* from NamnStad as t1 left join NamnStad as t2 on t1.Namn = t2.Namn where t1.Stad like 'Stockholm' group by t2.Id, t2.Namn, t2.Stad

INTEL CORE I7 3930K 3.20GHZ 12MB S-2011, FRACTAL DESIGN MIDITOWER DEFINE R3, CORSAIR HX 1050W, ASUS RAMPAGE IV FORMULA, Asus STRIX GTX970, CORSAIR 16GB DDR3 DOMINATOR QUAD 1866MHZ CL9 (4X4GB) Ljud: ASUS Xonar D2X/XDT 7.1 | Elac 5.1 +förstärkare | Cambridge dacmagic plus | Astro gaming A40 | Sennheiser HD 650
You ask me if I have a god complex? Let me tell you something, I am god!

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Feb 2005
Skrivet av IceDread:

Sant, glömde ta med group by, lägg på en group by t2.Id, t2.Namn, t2.Stad på slutet så blir det fint.

select t2.* from NamnStad as t1 left join NamnStad as t2 on t1.Namn = t2.Namn where t1.Stad like 'Stockholm' group by t2.Id, t2.Namn, t2.Stad

Det fixar dubletter, men inte ordningen som det presenteras.

Edit: och tar fortfarande ordentligt längre tid, storleksordningen tre magnituder.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2006
Skrivet av Gropenator:

Det fixar dubletter, men inte ordningen som det presenteras.

Något måste man väll kunna fixa själv?

Fine,

Lade på en order by, men för att slippa skriva staden man är ute efter 2 ggr (dvs i order by också...) så gjorde jag en variabel för det.

declare @stad nvarchar(50) = 'Stockholm' select t2.* from NamnStad as t1 left join NamnStad as t2 on t1.Namn = t2.Namn where t1.Stad like @stad group by t2.Id, t2.Namn, t2.Stad order by case when t2.Stad like @stad then 1 else 2 end

Och sen kan man efter önskemål lägga på ,t2.Namn eller vad man du vill sist i order by clausen givetvis...

INTEL CORE I7 3930K 3.20GHZ 12MB S-2011, FRACTAL DESIGN MIDITOWER DEFINE R3, CORSAIR HX 1050W, ASUS RAMPAGE IV FORMULA, Asus STRIX GTX970, CORSAIR 16GB DDR3 DOMINATOR QUAD 1866MHZ CL9 (4X4GB) Ljud: ASUS Xonar D2X/XDT 7.1 | Elac 5.1 +förstärkare | Cambridge dacmagic plus | Astro gaming A40 | Sennheiser HD 650
You ask me if I have a god complex? Let me tell you something, I am god!

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Feb 2005
Skrivet av IceDread:

Något måste man väll kunna fixa själv?

Fine,

Lade på en order by, men för att slippa skriva staden man är ute efter 2 ggr (dvs i order by också...) så gjorde jag en variabel för det.

declare @stad nvarchar(50) = 'Stockholm' select t2.* from NamnStad as t1 left join NamnStad as t2 on t1.Namn = t2.Namn where t1.Stad like @stad group by t2.Id, t2.Namn, t2.Stad order by case when t2.Stad like @stad then 1 else 2 end

Och sen kan man efter önskemål lägga på ,t2.Namn eller vad man du vill sist i order by clausen givetvis...

Och då blir den ännu långsammare.

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007
Skrivet av IceDread:

Något måste man väll kunna fixa själv?

Fine,

Lade på en order by, men för att slippa skriva staden man är ute efter 2 ggr (dvs i order by också...) så gjorde jag en variabel för det.

declare @stad nvarchar(50) = 'Stockholm' select t2.* from NamnStad as t1 left join NamnStad as t2 on t1.Namn = t2.Namn where t1.Stad like @stad group by t2.Id, t2.Namn, t2.Stad order by case when t2.Stad like @stad then 1 else 2 end

Och sen kan man efter önskemål lägga på ,t2.Namn eller vad man du vill sist i order by clausen givetvis...

Varför gruppera på alla kolumner? Varför gruppera alls när det inte används några aggregerande funktioner?

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2006
Skrivet av Gropenator:

Och då blir den ännu långsammare.

I stället för ett simpelt konstaterande som troligen är uppenbart för dig och andra med lite erfarenhet så borde du berättat varför och sen gissat på varför jag valde min lösning.

En 'union all' är alltid snabbast, men inte alltid möjlig beroende på datan, tabellerna, dubletter, osv. En 'union' (utan 'all') är däremot inte alltid snabbare än en join och bra för folk att se andra möjligheter att skriva en query. Har du sen index och tillräckligt med ram på servern så datan är snabbt tillgänlig så är skillnaden ofta åt endera håll inte stor i ms för just denna situation.
Du kunde också nämnt sp's, stored procedures, och hur queryn i en sp förbättrar prestandan.

INTEL CORE I7 3930K 3.20GHZ 12MB S-2011, FRACTAL DESIGN MIDITOWER DEFINE R3, CORSAIR HX 1050W, ASUS RAMPAGE IV FORMULA, Asus STRIX GTX970, CORSAIR 16GB DDR3 DOMINATOR QUAD 1866MHZ CL9 (4X4GB) Ljud: ASUS Xonar D2X/XDT 7.1 | Elac 5.1 +förstärkare | Cambridge dacmagic plus | Astro gaming A40 | Sennheiser HD 650
You ask me if I have a god complex? Let me tell you something, I am god!

Trädvy Permalänk
Medlem
Plats
Karlstad
Registrerad
Mar 2003

Jag är helt klart nöjd med snabbheten, jag kör endast top(50) då de senaste är intressana.

Grym hjälp har jag fått i tråden och lite lite mer kunskap, min MSSQL verktygslåda är rätt liten.

K#