Vinnaren i pepparkakshustävlingen!
2013-01-04, 14:53
  #1
Medlem
Är ny inom programmering i allmänhet och databaser i synnerhet. Därav är min query förmodligen ganska ineffektiv.

Håller på att anropa en databas från ett statistikprogram. Nu är det så att jag följande query verkar vara alldeles för krävande och jag undrar om någon vänlig själ kan hjälpa mig slipa till den lite.

Kod:
SELECT SUM(Amount + VATAmount) AS TotalInvoiceAmount
FROM Invoice
WHERE InvoiceType IN (0, 4) AND Service = 4 AND InvoiceNr NOT IN
(SELECT PrevInvoiceNr
FROM Invoice
WHERE InvoiceType = 4 AND Service = 4)
Citera
2013-01-04, 15:00
  #2
Medlem
Lite svårt att svara på då man inte ser datamodellen, och t.ex. förstår hur PreInvoiceNr fungerar. Antar att detta inte gör samma sak, eller?

Kod:
SELECT SUM(Amount VATAmount) AS TotalInvoiceAmount
FROM Invoice
WHERE InvoiceType 
AND Service 
Citera
2013-01-04, 15:26
  #3
Medlem
Ber om ursäkt, är ganska trött nu på slutet av veckan. Lite bakgrundsinfo kanske är på sin plats.

Det jag söker är summan av Amount och VATAmount hos alla relevanta fakturor (invoices).
InvoiceType är vilken sorts faktura där 0 är en vanlig faktura och 4 är omfakturering.
Jag måste jag även tvätta listan mot omfaktureringarna för att inte få med dubbla/felaktiga fakturor vilket endast går genom att utesluta InvoiceNr som även finns som PrevInvoiceNr.
Service är bara vilken tjänst det gäller.

Om det är något som jag behöver förklara ytterligare är det bara att fråga.
Citera
2013-01-04, 15:41
  #4
Medlem
Tycker inte din query är särskilt konstig. Finns det Index på dessa 4?

InvoiceType, Service, InvoiceNr, PrevInvoiceNr
Citera
2013-01-04, 15:47
  #5
Medlem
Tveksamt. Har inte heller tillgång direkt till databasen för att kolla. Kommer endast åt den via en DSN så vitt jag vet.
Citera
2013-01-04, 15:56
  #6
Medlem
Hm, ok. Det du kan göra är ju att selectera fram saker och lagra det i temporära tabeller/tabeller i minnet, som du sedan sätter Index på och använder.

Exempelvis om
Kod:
SELECT FROM Invoice 
går snabbare än
Kod:
SELECT SUM(Amount VATAmount) AS TotalInvoiceAmount FROM Invoice WHERE InvoiceType IN (04) AND Service 

Hoppas du förstod hur jag menade.
Citera
2013-01-04, 16:00
  #7
Medlem
Humm, jag tror det.
Får experimentera lite och se om jag får det till att fungera.
Citera
2013-01-05, 00:52
  #8
Medlem
Du vill "tvätta" så att du inte tar med fakturor som har blivit "omfakturerade" ?
Borde det int finnas något annat sätt förutom att se / jämföra med PreinvoiceNr på alla andra fakturor?
Tycker det borde finnas ett sätt att se ifall en faktura är giltig, UTAN att undersöka alla andra fakturor.

Borde kunna skriva om frågan mha join. Men vet inte om det blir snabbare..
Kod:
SELECT SUM(i1.Amount + i1.VATAmount) AS TotalInvoiceAmount
FROM Invoice i1 left join Invoice i2 on i1.invoicenr=i2.PrevInvoiceNR
WHERE i1.InvoiceType IN (0, 4) AND i1.Service = 4 
and (i2.PrevInvoiceNr is null or not ( i2.InvoiceType = 4 AND i2.Service = 4) );
Jag gissar att det är som tidigare skribent skrev; index är något som behövs för frågan.
Citera
2013-01-05, 15:38
  #9
Medlem
John-Pauls avatar
Citat:
Ursprungligen postat av Gurgler
Är ny inom programmering i allmänhet och databaser i synnerhet. Därav är min query förmodligen ganska ineffektiv.

Håller på att anropa en databas från ett statistikprogram. Nu är det så att jag följande query verkar vara alldeles för krävande och jag undrar om någon vänlig själ kan hjälpa mig slipa till den lite.

Kod:
SELECT SUM(Amount + VATAmount) AS TotalInvoiceAmount
FROM Invoice
WHERE InvoiceType IN (0, 4) AND Service = 4 AND InvoiceNr NOT IN
(SELECT PrevInvoiceNr
FROM Invoice
WHERE InvoiceType = 4 AND Service = 4)

Ofta är "NOT EXISTS" snabbare än "NOT IN"

Kod:
SELECT SUM(Amount + VATAmount) AS TotalInvoiceAmount
FROM Invoice I1
WHERE I1.InvoiceType IN (0, 4) AND I1.Service = 4 AND I1.InvoiceNr and NOT EXISTS
(SELECT 1
FROM Invoice I2
WHERE I1.InvoiceNr = I2.PrevInvoiceNr and I2.InvoiceType = 4 AND I2.Service = 4)
Citera
2013-01-11, 13:21
  #10
Medlem
Testade denna och den var långt bättre än min ursprungliga, vill tacka innerligt för din hjälp!

Citat:
Ursprungligen postat av sagonar
Kod:
SELECT SUM(i1.Amount + i1.VATAmount) AS TotalInvoiceAmount
FROM Invoice i1 left join Invoice i2 on i1.invoicenr=i2.PrevInvoiceNR
WHERE i1.InvoiceType IN (0, 4) AND i1.Service = 4 
and (i2.PrevInvoiceNr is null or not ( i2.InvoiceType = 4 AND i2.Service = 4) )

Vill även tacka alla andra som hjälpt mig med detta!
__________________
Senast redigerad av Gurgler 2013-01-11 kl. 14:00.
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