Jag hämtar data från 3 olika tabeller, och löste det tidigare med tre olika recordsets. Nu har jag studerat SQL lite mera och insett möjligheterna med joins. Men följande sträng tar upp emot 20 sekunder att köra, tidigare då jag hade 3 recordsets öppna tog det vanligtvis bara ett par sekunder... >FROM `kassabok`,`budget`,`kategorier` Hmm intressant... Och som ett litet tillägg kan jag säga att det räcker med att skriva JOIN i MySQL eftersom det är samma som INNER JOIN. jo, lösningen med budget tyckte jag var smart när jag designade den för att spara plats, men det är tydligen inte så smart ändå.. =) Det beror helt på vad Sessionsvärderna innehåller... Till exempel, innehåller Session("user") en siffra med 100% säkerhet är det inga problem. Så om jag förstår Martins inlägg rätt så innebär detta sättet att skriva join på de gemensamma värdena att datamängden som urvalet i WHERE satsen körs på redan är begränsat till de poster som har join-satsens angivna gemensamma värden? Nu förstod jag inte vad du menar. =) en kort fråga om sql-satsen du föreslog: Ja, det kan man. Och som du ser behöver man inte AS i MySQL utan man sätter bara namnet direkt efter. det som tidigare hämtade summan av beloppen såg ut så här Men en sak till - nu tas endast de kategorier med som har belopp i kassabok-tabellen, om det vore så att jag ville visa även de kategorier som inte har något värde (0) hur skriver jag då? typ HAVING kategori.id>0 eller nåt sånt? Jag ser inte riktigt hur du har byggt upp din databas. Har det inte att göra med left eller right joins? jag har försökt läsa lite om det men blir inte klok på det hela, har även testat med både left och right join, men det blir ingen skillnad på resultatet. Problemet, som jag ser det, ligger i att du inte på något sätt kan säga att en viss kategori hör till en viss användare om det inte finns någon koppling (kat.id = kassa.id). När jag satte in det där extra som du tipsade så kom detta felet... Är inte säker på att du kan använda budget.m?, kanske om det som ska ersättas med en siffra... Detta är min connection string Jo, men då måste jag ju ha tid att ta mig över inlärningströskeln också... så jag vet inte vilken investering som är tidseffektivast =) Jag insåg just det idiotiska i fältbenämningen m1, m2 osv. icke normaliserad, eller vad du sa att det kallades... skulle göra en grej som vore superlätt med en "rätt" designad databas... nu måste jag hårdkoda en massa... designar nog ändå inte om databasen förrän nästa version, jag slutför nog dock detta i asp script först, så får vi ta nästa version i .net (tittade lite på det i helgen, det verkar ju inte oöverkomligt svårt ens för mig :P ) Ja, det blir direkt mycket svårare att hantera då man har flera fält då du inte på ett lätt sätt kan kontrollera data i alla fält samtidigt... Jag stänger den här tråden nu... har inte fått till det ännu, men jag ska läsa på lite mer om outer joins så får vi se om jag kan lyckas visa även rader utan motsvarighet i kassaboken.. ska förresten gå en 5p kurs i sommar om databasdesign, så förmodligen är det slut på tabeller á la "select m"& var_manad& " where"... ;-pSnabbare med 3 recordsets än en SQL sats?
uppenbara fel? ska man använda uttrycken <b>inner join on</b> istället för en massa where-satser?
rs.open "SELECT SUM(kassabok.belopp) AS summa, kategorier.kategori AS namn, kategorier.id AS id, budget.m" & manad & " AS budget FROM `kassabok`,`budget`,`kategorier` WHERE budget.kategori = kategorier.id AND budget.year=" & session("year") & " AND kassabok.kategori = kategorier.id AND kategorier.inkomst=TRUE AND kassabok.user=" & session("user") & " AND kassabok.month=" & manad & " AND kassabok.year=" & session("year") & " GROUP BY kassabok.kategori",ConnSv: Snabbare med 3 recordsets än en SQL sats?
Du får nog läsa på lite mer om SQL :-)
Ovanstående skapar inte en join mellan tabellerna. Vad den gör är att den tar alla rader i kassabok och kombinerar med alla rader i budget och sen kombinerar det resultatet med alla rader i kategorier.
dvs om varje tabell innehåller 100 rader får du ett resultat på 100^3 = 1 miljon rader. På detta resultat appliceras sen din where sats.
I de flesta fall brukar databasen göra om where till inner joins där det går men i det här fallet verkar det inte ske. Antagligen saknas det någon koppling i where satsen som behövs för ett entydigt resultat.
Använd "inner join" så blir det lättare.
Sv:Snabbare med 3 recordsets än en SQL sats?
jag "läste på" på databases.about.com och där framställer de det som att det inte är någon skillnad.
Mitt problem var att jag inte såg hur jag kunde precisera vilka where som gällde för vilka fält/tabeller när jag skrev två st. "join" det gick bra så länge det var bara 2 tabeller, men när jag plockade in den tredje fixade jag det inte...
Så här står det förresten på about.com
SELECT lastname, firstname, tag
FROM drivers, vehicles
WHERE drivers.location = vehicles.location
AND drivers.class = vehicles.class
The same query could be rewritten as:
SELECT lastname, firstname, tag
FROM drivers INNER JOIN vehicles ON drivers.location = vehicles.location
WHERE drivers.class = vehicles.class
ref.
http://databases.about.com/od/sql/l/aajoins3.htmSv: Snabbare med 3 recordsets än en SQL sats?
Tror din SQL sats blir något i stil med följande. Men jag ser att designen inte är den bästa, till exempel att du har "budget.m" & manad innebär att databasen inte är normaliserad. Dessutom måste du se till att ta hand om eventuella risker med SQL injection som skulle kunna uppstå i med denna sats.
<code>
"SELECT SUM(kassa.belopp) summa, kategorier.kategori namn, kategorier.id id, budget.m" & manad & " budget FROM `kassabok` kassa
JOIN `kategorier` kat ON kat.id = kassa.kategori
JOIN `budget` b ON b.kategori = kat.id
WHERE b.year = " & session("year") & " AND kat.inkomst = 1 AND kassa.user = " & session("user") & " AND kassa.month = " & manad & " GROUP BY kat.id"
</code>Sv:Snabbare med 3 recordsets än en SQL sats?
ang. injection - eftersom sessionsvariabeln är säker (eller?) och manad är konverterad till Integer (tidigare i skriptet) finns väl ingen risk för injection, eller? skall som sagt köra cmd framöver, men jag trodde att det var säkert så här?Sv: Snabbare med 3 recordsets än en SQL sats?
Du har rätt i att så länge användarna inte direkt kommer åt att ändra värderna på sessionerna och du garanterat alltid har kontrollerat att de sätts till sådana värden som inte kan skada är ditt sätt säkert.
Men det finns alltid en risk att man missar att kontrollera ett värde innan en session sätts och då är din kod väldigt osäker.
Men när du konverterar till Command objektet blir det nog bra ;)Sv:Snabbare med 3 recordsets än en SQL sats?
Då är det ju fullständigt korkat att bara skriva alla tabeller och sedan börja villkora...Sv: Snabbare med 3 recordsets än en SQL sats?
Men det är alltid säkrare att skriva ut alla JOIN, och personligen tycker jag det blir mycket tydligare också.
Vissa, databasen gör om satserna så gott den kan, men det är ändå bara någon som programmerat de algoritmerna och de är inte perfekta.
Se en INNER JOIN som så att databasen bara tar ut de rader som "finns" i båda tabellerna.
(LEFT | RIGHT) OUTER JOIN tar alla raderna från tabellen på den vänstra/högra sidan av ON.
Alltså, vid den tidpunkten som WHERE körs blir det bara på en mindre mängd rader = snabbare.
Sen måste du också kontrollera att du har INDEX på alla kolumner som du joinar, annars kan det bli ganska segt...Sv: Snabbare med 3 recordsets än en SQL sats?
du kan alltså definiera ett eget namn på tabellen efter FROM, men det egna namnet kan du använda redan innan FROM delen, där du väljer ut fälten?Sv:Snabbare med 3 recordsets än en SQL sats?
Ta ett seniario där du kombinerar en tabell med sig själv. Där behöver du kunna döpa om dem och använda det omdöpta namnet direkt efter SELECT för att kunna säga från vilken av "instanserna" av tabellen du vill ha data.
Databasen läser inte SQL satsen från början till slut utan delar upp den i delar som den sedan arbetar med.Sv: Snabbare med 3 recordsets än en SQL sats?
"SELECT belopp FROM kassabok
WHERE kategori=" & rs("id") & " AND `year`=" & session("year") & " AND `month`=" & manad"
urvalet fungerar antingen inte som det är tänkt i den ny akombinerade satsen, eller så gick det inte att utläsa ur mitt knaggliga försök vad jag ville ha gjort... men nu hämtas i alla fall ett allt för stort värde på SUM()...
<b>Falskt alarm =) jag hade glömt lägga in året även i kassabok-villkoret. nu funkar den som smort )= TACK!!</b> Nu skall jag nog fixa att ordna de andra nestlade rs:en också enligt denna mallen. tack!Sv:Snabbare med 3 recordsets än en SQL sats?
Sv: Snabbare med 3 recordsets än en SQL sats?
Försök ge en överblick över de tre tabellerna och viktigaste kolumnerna och exempel på alla kombinationer av data du vill ha ut.Sv:Snabbare med 3 recordsets än en SQL sats?
Från tabellen kategorier hämtas som det är nu alla kategorier som har en motsvarighet i tabellen kassabok. Budget hämtas dock oavsett om där finns en nolla eller värde. Jag vill att alla kategorier skall hämtas oavsett om det finns matchande rader i kassaboken.Sv: Snabbare med 3 recordsets än en SQL sats?
Du måste beskriva lite mer hur du vill ha det. Tror det kan vara något i stil med
<code>
SELECT SUM(kassa.belopp) summa, k.kategori namn, k.id, budget.m... budget FROM `kategorier` k
LEFT OUTER JOIN `kassabok` kassa ON (kassa.kategori = k.id AND kassa.user = ?user)
LEFT OUTER JOIN `budget` b ON b.kategori = kassa.kategori
WHERE b.year = ?year AND kat.inkomst = 1 AND kassa.month = ?month
GROUP BY k.id
</code>
Du får byta ut m... och alla ?... mot dina värden.Sv:Snabbare med 3 recordsets än en SQL sats?
<b>
Microsoft OLE DB Provider for ODBC Drivers error '80040e21'
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done. </b>
som jag stött på tidigare men fortfarande inte förstår vad det betyder/varför det kommer.
och koden...
SELECT SUM(kassa.belopp) summa, kat.kategori namn, b.m? budget FROM `kassabok` kassa
LEFT OUTER JOIN `kategorier` kat ON (kat.id = kassa.kategori AND kassa.user = ?)
LEFT OUTER JOIN `budget` b ON b.kategori = kat.id
WHERE b.year = ? AND kat.inkomst = 1 AND kassa.user = ? AND kassa.month = ? AND kassa.year = ?
GROUP BY kat.id
set rs = cmd.execute (,array(manad,session("user"),session("year"),session("user"),manad,session("year")))Sv: Snabbare med 3 recordsets än en SQL sats?
Vad felet beror på vet jag inte, hittade denna http://bugs.mysql.com/bug.php?id=3855
Kolla om det kan hjälpa dig. Vad använder du för connectionstring?Sv:Snabbare med 3 recordsets än en SQL sats?
SET Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "driver={MySQL ODBC 3.51 Driver};server=mysql.mydomain.com;database=mydatabase;uid=myuserid;pwd=mypassword"
Såg i länken du skickade att man bl a kunde testa att lägga på option=3 eller något sådant. Kanske får testa lite runt det när jag får möjlighet att sätta mig nästa gång... =) jobbet binder ju upp en hela dagarna (ekonomi) och så är det fru, hund och snart barn när man kommer hem =) målet är att i alla fall få ordning på sidan innan sommaren är slut för sen blir det som sagt flygledare av karln... =)Sv:Snabbare med 3 recordsets än en SQL sats?
Sv: Snabbare med 3 recordsets än en SQL sats?
Sv:Snabbare med 3 recordsets än en SQL sats?
Och ja, .NET är inte så hemskt oöverkomligt =)Sv: Snabbare med 3 recordsets än en SQL sats?