Permalänk
Medlem

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

Visa signatur

K#

Permalänk
Medlem

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

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Fuling :

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

Permalänk
Medlem
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.

Visa signatur

K#

Permalänk
Medlem

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.

Permalänk

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'

Permalänk
Medlem

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

Permalänk
Medlem
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)

Visa signatur

K#

Permalänk
Medlem

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.

Visa signatur

Intel Core i7 8700K, MSI GeForce GTX 1080 Ti 11GB Gaming X, Samsung 960 EVO 1TB, MSI Z370 GAMING M5, Corsair 32GB (4x8GB) DDR4 3200MHz CL16 Vengeance, EVGA Supernova G3 850W

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!

Permalänk
Medlem
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

Visa signatur

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!

Permalänk
Medlem

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?

Permalänk
Medlem
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

Visa signatur

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!

Permalänk
Medlem
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.

Visa signatur

K#

Permalänk
Medlem
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.

Permalänk
Medlem
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

Visa signatur

Intel Core i7 8700K, MSI GeForce GTX 1080 Ti 11GB Gaming X, Samsung 960 EVO 1TB, MSI Z370 GAMING M5, Corsair 32GB (4x8GB) DDR4 3200MHz CL16 Vengeance, EVGA Supernova G3 850W

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!

Permalänk
Medlem
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.

Permalänk
Medlem
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...

Visa signatur

Intel Core i7 8700K, MSI GeForce GTX 1080 Ti 11GB Gaming X, Samsung 960 EVO 1TB, MSI Z370 GAMING M5, Corsair 32GB (4x8GB) DDR4 3200MHz CL16 Vengeance, EVGA Supernova G3 850W

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!

Permalänk
Medlem
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.

Permalänk
Medlem
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?

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
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.

Visa signatur

Intel Core i7 8700K, MSI GeForce GTX 1080 Ti 11GB Gaming X, Samsung 960 EVO 1TB, MSI Z370 GAMING M5, Corsair 32GB (4x8GB) DDR4 3200MHz CL16 Vengeance, EVGA Supernova G3 850W

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!

Permalänk
Medlem

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.

Visa signatur

K#