webForumDet fria alternativet

Enklare SQL-fråga. Inte ens Gud skulle förlåta mig...

Databaser & SQL

23 svar · 1 491 visningar · startad av oskars

Medlem sedan nov. 20051 317 inlägg
Frågan#1

Hej...

ja, jag vet... jag kan inte göra ordentliga SQL-frågor.

Set oCount1 = Connect.Execute("SELECT COUNT(*) AS antal1 FROM Users WHERE Projekt = "&RecSet("ID")&" AND sID ='"&Session("userID")&"' AND AK = 0 AND GS = 0 AND KOrder = 0")
Set oCount2 = Connect.Execute("SELECT COUNT(*) AS antal2 FROM Users WHERE Projekt = "&RecSet("ID")&" AND sID ='"&Session("userID")&"' AND AK = 1 AND GS = 0 AND KOrder = 0")
Set oCount3 = Connect.Execute("SELECT COUNT(*) AS antal2 FROM Users WHERE Projekt = "&RecSet("ID")&" AND sID ='"&Session("userID")&"' AND GS = 1 AND KOrder = 0")
Set oCount4 = Connect.Execute("SELECT COUNT(*) AS antal4 FROM Users WHERE Projekt = "&RecSet("ID")&" AND sID ='"&Session("userID")&"' AND KOrder = 1")

Adresser = oCount1("antal1")
AK = oCount2("antal2")
GS = oCount3("antal3")
Ordrar = oCount4("antal4")

Set oCount = Connect.Execute("SELECT SUM(case when KOrder = 1 then 1 else 0 end) as antalOrdrar, " & _
				         "SUM(case when KOrder = 0 AND AK = 1 AND GS = 0 then 1 else 0 end) as antalAK " & _
				         "FROM Users WHERE sID = '"&Session("user")&"' AND Projekt = "&RecSet("ID")&"")

set oCount = Connect.Execute("SELECT COUNT(*) AS antal FROM Users WHERE sID ='"&Session("userID")&"' AND KOrder = 1")
intMinaOrdrar = oCount("antal")

set oCount = Connect.Execute("SELECT COUNT(*) AS antal FROM Users WHERE sID ='"&Session("userID")&"' AND KOrder = 3")
intMinaAtgardas = oCount("antal")

set oCount = Connect.Execute("SELECT COUNT(*) AS antal FROM Nyhetsbrev WHERE sID ='"&Session("userID")&"' AND KOrder = 33")
intMinaReturer = oCount("antal")

Jag gör alla dessa SQL-frågor för att få ut statistik från databasen... det är alltså bara siffror jag vill ha ut. Jag vet hur man gör om det är olika siffror från samma tabell, men här är det ju hundra olika siffror från hundra olika tabeller... :o

Vill någon visa mig ett exempel på hur jag gör om dessa SQL-frågor? Eller kanske visa ett exempel på hur man gör flera COUNT(*) med olika villkor i flera olika tabeller. Alltså en fråga per tabell, fast flera frågor i en SQL-sträng..

:r :r :r Hoppas ni förstår mig!

Tacksam för hjälp!

Mvh
Oskar

Medlem sedan dec. 200012 464 inlägg
#2

Du har ju ett exempel där du använder case för att få flera count i samma fråga.

Du kan använda union för att sammanfoga flera resultat till 1

select 1, count(*)  as antal
  FROM ...
 union all 
 select 2, COUNT(*) 
   FROM 
...

första siffran är till för att veta vilket resultat som är vad.

Medlem sedan nov. 20051 317 inlägg
#3

Tusen tackar! Jag ska försöka mig på detta direkt!

Men du... vad betyder egentligen "then 1 else 0"... betyder det att om den uppfyller mina villkor så ska den plussa med 1, annars 0?

Medlem sedan nov. 20051 317 inlägg
#4

Jag får följande fel:

[MySQL][ODBC 3.51 Driver][mysqld-5.1.22-rc-community]The used SELECT statements have a different number of columns

Jag förstår inte hur jag har misslyckats :) Alla tre tabellerna jag hämtar ifrån har lika många kolumner!

Medlem sedan dec. 200012 464 inlägg
#5

Ja.

Medlem sedan sep. 2006867 inlägg
#6

Det beror väl på att du valt att hämta olika antal kolumner i dina SELECT-satser, snarare än hur många faktiska kolumner som råkar finnas i respektive tabell? Tror jag?!

Medlem sedan nov. 20051 317 inlägg
#7

Så här ser SQL-strängen ut som jag får felmeddelandet med...

set oCount = Connect.Execute("SELECT SUM(case when KOrder = 1 then 1 else 0 end) as intMinaOrdrar, " & _
				    	 "SUM(case when KOrder = 3 then 1 else 0 end) as intMinaAtgardas " & _
				    	 "FROM Adresser2006 WHERE sID = '"&Session("userID")&"' UNION ALL " & _
				    	 
						 "SELECT SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger, " & _
				    	 "SUM(case when KOrder = 3 then 1 else 0 end) as intMinaReturOK, " & _
						 "SUM(case when KOrder = 33 then 1 else 0 end) as intMinaReturer, " & _
						 "SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA " & _
				    	 "FROM Arkiv WHERE sID ='"&Session("userID")&"' UNION ALL " & _
				    	 
						 "SELECT SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA_Arkiv, " & _
				    	 "SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger_Arkiv, " & _
						 "SUM(case when KOrder = 5 then 1 else 0 end) as intMinaEjGodkanda " & _
				    	 "FROM ArkivUtanOrdernummer WHERE sID ='"&Session("userID")&"' AND KOrder = 33")

Ser inte vad som kan vara fel?

Medlem sedan juni 200032 967 inlägg
#8

precis som headbug skriver - du hämtar olika antal "fält" i dina delfrågor i UNION.
I den första hämtar du två värden, i den andra hämtar du fyra, och i den sista hämtar du tre.

Medlem sedan nov. 20051 317 inlägg
#9

Så jag måste hämta lika många värden i varje fråga alltså? Jobbigt... då får jag typ hitta på några låtsas värden, så att det funkar?

Medlem sedan juni 200032 967 inlägg
#10

Jobbigt och jobbigt...

,NULL, NULL
Medlem sedan nov. 20051 317 inlägg
#11

Hehe, var ju inte så jobbigt :e Tack!

	set oCount = Connect.Execute("SELECT SUM(case when KOrder = 1 then 1 else 0 end) as intMinaOrdrar, " & _
						    	 "NULL, NULL, SUM(case when KOrder = 4 then 1 else 0 end) as intMinaAtgardas " & _
						    	 "FROM Adresser2006 WHERE sID = '"&Session("userID")&"' UNION ALL " & _
						    	 
								 "SELECT SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger, " & _
						    	 "SUM(case when KOrder = 3 then 1 else 0 end) as intMinaReturOK, " & _
								 "SUM(case when KOrder = 33 then 1 else 0 end) as intMinaReturer, " & _
								 "SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA " & _
						    	 "FROM Arkiv WHERE sID ='"&Session("userID")&"' UNION ALL " & _
						    	 
								 "SELECT SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA_Arkiv, " & _
						    	 "NULL, SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger_Arkiv, " & _
								 "SUM(case when KOrder = 5 then 1 else 0 end) as intMinaEjGodkanda " & _
						    	 "FROM ArkivUtanOrdernummer WHERE sID ='"&Session("userID")&"'")

När jag kör denna koden så får jag följande felmeddelande:

Rad: 30
Kolumn: -1
Beskrivning: Objektet kunde inte hittas i mängden med det begärda namnet eller numret.

Rad 30:

intMinaReturer = oCount("intMinaReturer")

Den verkar inte vilja ta fram några siffror från UNION 1 och UNION 2... Why oh why?

Medlem sedan juni 200032 967 inlägg
#12

Du måste sätta fältnamnen på den översta frågan i din UNION. Vad som står i de undre har ingen som helst betydelse.

Dessutom får du tre poster, det är du med på? Du måste alltså köra movenext en gång, hämta dina värden från select nummer 2, köra movenext och sedan hämta värdena från select nummer 3.

Medlem sedan nov. 20051 317 inlägg
#13

Tack @nders!

Vad menar du med att sätta fältnamnen i första frågan? Jag har ju skrivit in fältnamnet där: "KOrder"

Okej, "movenext" om jag vill ha tag på mina övriga union! Ska testa det direkt!

Det enda jag inte förstår är hur jag sätter flätnamnen!

Medlem sedan juni 200032 967 inlägg
#14

En rad/post i ett recordset kan ju inte ha egna namn på fälten. Därför sätts fältnamnen i den överst frågan.
Om du sätter fältnamn i de två under ignoreras de.

Om du kör följande fråga:

SELECT 1 AS Foo, 2 AS Bar, 3 AS Foobar
UNION
SELECT 2 AS Bla, 1 AS Wee, 4 AS Woo
UNION
SELECT 5 AS Peh, 3 AS Kah, 1 AS Blii

Så kommer ditt recordset se ut så här:

Foo     Bar     Foobar
1       2       3
2       1       4
5       3       1

Om du nu förstår hur resultatet ser ut, blir det nog lättare för dig att hämta ut dina värden.
Frågan är om det inte är lättare att lösa med subqueries - resultatet blir iaf lättare att tolka.

Medlem sedan sep. 2006867 inlägg
#15

Jo när du skriver SELECT och sedan gör en UNION på andra tabeller så måste du veta vad den RESULTERANDE mish-mashens kolumner heter.

Detta bestäms alltså av vad kolumnerna har för namn i FÖRSTA frågan.

Om du studerar din första fråga så heter kolumnerna

intMinaOrdrar, vaddå?, vaddå? samt intMinaAtgardas

Så du får skriva NULL as kolumn2, NULL as kolumn3 eller vad du nu vill att dom ska heta så att du kan plocka ut dina värden ur det resulterande UNION-svaret.

/red: jaja, jag tänker för länge när jag formulerar mig :)

Medlem sedan nov. 20051 317 inlägg
#16

Oj, nä, jag fattar ingenting. :r

Nu när jag försöker loopa igenom recsetet så hittar den alla siffror i första frågan, men stoppar sig direkt på andra frågan. Men jag har inte gjort ändringarna du skrev i senaste inlägget, för jag förstår dom inte...

Så du tror subqueries är bättre? Men det känsn som att jag är så nära att lyckas med UNION ALL nu... men vad är det för ändringar jag måste göra för att få ordning på min fråga? Jag vet att du skrev det i senaste inlägget, men jag förstod inte....

:r :stud

EDIT: Nu såg jag Headbugs inlägg!!! Ska testa det!!!

Medlem sedan nov. 20051 317 inlägg
#17

Så här ser det ut nu:

set oCount = Connect.Execute(""& _

	"SELECT SUM(case when KOrder = 1 then 1 else 0 end) as intMinaOrdrar, " & _
	"SUM(case when KOrder = 4 then 1 else 0 end) as intMinaAtgardas, NULL as Null1, NULL as Null2 " & _
	"FROM Adresser2006 WHERE sID = '"&Session("userID")&"' UNION ALL " & _
	
	"SELECT SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger, " & _
	"SUM(case when KOrder = 3 then 1 else 0 end) as intMinaReturOK, " & _
	"SUM(case when KOrder = 33 then 1 else 0 end) as intMinaReturer, " & _
	"SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA " & _
	"FROM Arkiv WHERE sID ='"&Session("userID")&"' UNION ALL " & _
	
	"SELECT SUM(case when KOrder = 44 then 1 else 0 end) as intMinaAA_Arkiv, " & _
	" SUM(case when KOrder = 2 then 1 else 0 end) as intMinaTelefonanger_Arkiv, " & _
	"SUM(case when KOrder = 5 then 1 else 0 end) as intMinaEjGodkanda, NULL as Null3 " & _
	"FROM ArkivUtanOrdernummer WHERE sID ='"&Session("userID")&"'")

Tal = 0
Do Until oCount.EOF
Tal = Tal + 1

	If Tal = 1 Then
		intMinaOrdrar = oCount("intMinaOrdrar")
		intMinaAtgardas = oCount("intMinaAtgardas")

	ElseIf Tal = 2 Then
		intMinaTelefonanger = CInt(oCount("intMinaTelefonanger"))
		intMinaReturOK = oCount("intMinaReturOK")
		intMinaReturer = oCount("intMinaReturer")
		intMinaAA = oCount("intMinaAA")
	ElseIf Tal = 3 Then
		intMinaAA = CInt(intMinaAA) + CInt(oCount("intMinaAA_Arkiv"))
		intMinaTelefonanger = CInt(intMinaTelefonanger) + CInt(oCount("intMinaTelefonanger_Arkiv"))
		intMinaEjGodkanda = oCount("intMinaEjGodkanda")
	End If

oCount.MoveNext
Loop

Men jag får följande felmeddelande:
Rad: 39
Kolumn: -1
Beskrivning: Objektet kunde inte hittas i mängden med det begärda namnet eller numret.

Rad39: intMinaTelefonanger = CInt(oCount("intMinaTelefonanger"))

Alltså stoppar den direkt i andra frågan... Men nu skrev agj ju ändå in Null AS Null1 osv...

Medlem sedan juni 200032 967 inlägg
#18

Du ska ha fältnamnen du vill kalla på i den översta frågan.
Hur många gånger måste vi skriva det? ;)

Medlem sedan nov. 20051 317 inlägg
#19

@nders skrev:

Du ska ha fältnamnen du vill kalla på i den översta frågan.
Hur många gånger måste vi skriva det? ;)

Jag gräver ner mig!

Hur kan jag få in fältnamnen från fråga2 och fråga3 i fråga1? Hur ska jag då kunna länka ihop dom i fråga2 och fråga3?

Ska jag typ bara skriva så här i slutet av fråga1:

Null AS intMinaTelefonanger, Null AS intMinaReturOK (som några av frågorna i fråga2 heter) osv osv...

EDIT: Är nära nu! Testade det jag skrev här! hehe

Medlem sedan mars 20034 471 inlägg
#20

oskars skrev:

Hur kan jag få in fältnamnen från fråga2 och fråga3 i fråga1?

Skriv dit dem! Flytta upp namngivningen till första frågan!!!

//I princip har du 
SELECT K1 as intMinaOrdrar, K2 as intMinaAtgardas, K3 as Null1, K4 as Null2 
FROM ....
UNION ALL 
SELECT K1 as intMinaTelefonanger, K2 as intMinaReturOK, K3 as intMinaReturer, K4 as intMinaAA 
FROM ....
UNION ALL 
SELECT K1 as intMinaAA_Arkiv, K2 as intMinaTelefonanger_Arkiv, K3 as intMinaEjGodkanda, K4 as Null3 
FROM...

I resultatet kommer ALLA K1 att få samma namn, alla K2 att få samma namn osv... Och det namn de får är det namn de får i den första SELECT-satsen. Alltså: intMinaOrdrar, intMinaAtgardas, Null1, och Null2

Tänk så här: Alla dessa rader hamnar i SAMMA tabell, självklart kan varje kolumn i den tabellen bara ha ett kolumnnamn. :)

271 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
124 ms — deklarationer (db)
0 ms — hämta statistik (cache)
144 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)