Vinnaren i pepparkakshustävlingen!
2010-10-14, 10:40
  #1
Medlem
Basers avatar
Hej,


Jag ska först få ut de säljare med högst provision och sedan de 5 säljare med flest antal kunder. Jag kan lösa det genom att göra 2 olika frågor, dock skulle jag behöva kombinera resultaten i en vy. Jag kör följande kod:
Säljare med mest provision:

SELECT TOP (5) dbo.personal.fornamn, dbo.personal.efternamn, dbo.personal.personal_id AS Säljarid, SUM(dbo.produkt.provision * dbo.lonekat.provisionsandel)
AS Provision
FROM dbo.personal INNER JOIN
dbo.bokning ON dbo.personal.personal_id = dbo.bokning.saljare_id INNER JOIN
dbo.produkt ON dbo.bokning.produkt_id = dbo.produkt.produkt_id INNER JOIN
dbo.lonekat ON dbo.personal.lonekat_id = dbo.lonekat.lonekat_id
GROUP BY dbo.personal.personal_id, dbo.personal.fornamn, dbo.personal.efternamn
ORDER BY Provision DESC

Säljare med flest kunder:

SELECT TOP (5) dbo.personal.fornamn, dbo.personal.efternamn, dbo.personal.personal_id AS Säljarid, COUNT(dbo.bokning.saljare_id * dbo.kund.kundansvarig_id)
AS Antalkunder
FROM dbo.bokning INNER JOIN
dbo.kund ON dbo.bokning.kund_id = dbo.kund.kund_id INNER JOIN
dbo.personal ON dbo.bokning.saljare_id = dbo.personal.personal_id AND dbo.kund.kundansvarig_id = dbo.personal.personal_id
GROUP BY dbo.personal.personal_id, dbo.personal.fornamn, dbo.personal.efternamn
ORDER BY Antalkunder DESC

Kan man joina frågorna på något sätt, eller bygga ihop dom till endast en fråga? Så fort jag tar med kundtabellen i fråga 1 blir det helt annat resultat på den första queryn givetvis. Så jag vet inte riktigt heller hur jag skulle lyckas att kombinera dom i en fråga..

Lite hjälp skulle uppskattas!

Mvh Baser
Citera
2010-10-14, 10:53
  #2
Moderator
Protons avatar
Citat:
Ursprungligen postat av Baser
Hej,


Jag ska först få ut de säljare med högst provision och sedan de 5 säljare med flest antal kunder. Jag kan lösa det genom att göra 2 olika frågor, dock skulle jag behöva kombinera resultaten i en vy. Jag kör följande kod:
Säljare med mest provision:

SELECT TOP (5) dbo.personal.fornamn, dbo.personal.efternamn, dbo.personal.personal_id AS Säljarid, SUM(dbo.produkt.provision * dbo.lonekat.provisionsandel)
AS Provision
FROM dbo.personal INNER JOIN
dbo.bokning ON dbo.personal.personal_id = dbo.bokning.saljare_id INNER JOIN
dbo.produkt ON dbo.bokning.produkt_id = dbo.produkt.produkt_id INNER JOIN
dbo.lonekat ON dbo.personal.lonekat_id = dbo.lonekat.lonekat_id
GROUP BY dbo.personal.personal_id, dbo.personal.fornamn, dbo.personal.efternamn
ORDER BY Provision DESC

Säljare med flest kunder:

SELECT TOP (5) dbo.personal.fornamn, dbo.personal.efternamn, dbo.personal.personal_id AS Säljarid, COUNT(dbo.bokning.saljare_id * dbo.kund.kundansvarig_id)
AS Antalkunder
FROM dbo.bokning INNER JOIN
dbo.kund ON dbo.bokning.kund_id = dbo.kund.kund_id INNER JOIN
dbo.personal ON dbo.bokning.saljare_id = dbo.personal.personal_id AND dbo.kund.kundansvarig_id = dbo.personal.personal_id
GROUP BY dbo.personal.personal_id, dbo.personal.fornamn, dbo.personal.efternamn
ORDER BY Antalkunder DESC

Kan man joina frågorna på något sätt, eller bygga ihop dom till endast en fråga? Så fort jag tar med kundtabellen i fråga 1 blir det helt annat resultat på den första queryn givetvis. Så jag vet inte riktigt heller hur jag skulle lyckas att kombinera dom i en fråga..

Lite hjälp skulle uppskattas!

Mvh Baser
Kan du inte UNIONa ihop dina resultat, eftersom frågorna innehåller samma antal kolumner och det verkar vara samma data med?
Citera
2010-10-14, 12:20
  #3
Medlem
Basers avatar
Citat:
Ursprungligen postat av Proton
Kan du inte UNIONa ihop dina resultat, eftersom frågorna innehåller samma antal kolumner och det verkar vara samma data med?

Hur skulle jag göra det? Tack för hjälpen!
Citera
2010-10-14, 12:33
  #4
Medlem
skulle följande funka?
du tar alltså varje fråga och gör en subselect av dem. denna kommer att fungera som en vanlig tabell som du kan joina ihop.

Kod:
select top 5 *
from (
        
SELECT dbo.personal.fornamndbo.personal.efternamndbo.personal.personal_idSUM(dbo.produkt.provision dbo.lonekat.provisionsandel) AS Provision
        FROM dbo
.personal INNER JOIN
        dbo
.bokning ON dbo.personal.personal_id dbo.bokning.saljare_id INNER JOIN
        dbo
.produkt ON dbo.bokning.produkt_id dbo.produkt.produkt_id INNER JOIN
        dbo
.lonekat ON dbo.personal.lonekat_id dbo.lonekat.lonekat_id
        GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn
    
) as A
inner join 
(
        
SELECT dbo.personal.fornamndbo.personal.efternamndbo.personal.personal_idCOUNT(dbo.bokning.saljare_id dbo.kund.kundansvarig_id) AS Antalkunder
        FROM dbo
.bokning INNER JOIN
        dbo
.kund ON dbo.bokning.kund_id dbo.kund.kund_id INNER JOIN
        dbo
.personal ON dbo.bokning.saljare_id dbo.personal.personal_id AND dbo.kund.kundansvarig_id dbo.personal.personal_id
        GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn
    
) as B
on a
.personal_id b.personal_id
order by provision
antalkunder 
Citera
2010-10-14, 14:05
  #5
Medlem
Ovanstående svar är nog inte riktigt vad TS är ute efter. TS vill ha de 5 säljare med högst provision och sedan de 5 säljare med flest antal kunder - alltså inte nödvändigtvis samma 5 säljare.

För att svara på frågan hur UNION fungerar så sätter du bara detta nyckelord emellan två SELECT satser och dessa kommer att slås samman till ett resultatset. Se bara till att det är samma antal kolumner, samma datatyper och samma kolumnnamn (dvs definiera dessa endast i den första SELECT satsen). För ditt exempel kan det vara en idé att även slänga in en sorteringskolumn som du i första satsen sätter till 1 och i den andra sätter till 2 (osv. vid flera satser). På så sätt kan du hålla i sär de två satserna i det slutliga resultatsetet genom att alltid sortera på sorteringskolumen i första hand och värdekolumer i andra hand.

Exempel:

Kod:
SELECT 1 AS [One], 2 AS [Two], 3 AS [Three]
UNION ALL
SELECT 1, 4, 5
Citera
2010-10-14, 15:42
  #6
Medlem
Citat:
Ovanstående svar är nog inte riktigt vad TS är ute efter. TS vill ha de 5 säljare med högst provision och sedan de 5 säljare med flest antal kunder - alltså inte nödvändigtvis samma 5 säljare.

nej jag håller med. jag var lite osäker på vad det egentligen var som TS ville ha ut. men om man säger såhär. om man använder sig av en union all så kommer man att få andra problem. först och främst så antar jag att datatypen för sum och count blir olika i nuvarande form. count blir int medan sum borde kunna ge en float. detta kan man enkelt lösa genom sum körs först och man konvertar counten till en float (om det inte görs implicit). problemet kommer dock att uppstå om man faktiskt har en säljare som hamnar top 5 på bägge listorna. hur skiljer man då på vad som är vad? man skulle iofs kunna säga att dom översta fem är provision och de undre fem är antal kunder, men det är inte så bra att bygga in den typen av logik. om man skulle vilja ha top 6 istället så måste man ändra både i vyn och i vyns konsument.

om målet är att endast få en fråga mot databasen så skulle jag istället ha gjort en vy där man plockar ut det data som är intressant och sedan har affärslogiken i applikationen. du skulle ju istället kunna ta top 10 av frågan som jag skickade och sortera datat i applikationen för att få ut de två listorna och kunna presentera dessa. ska man hårddra det så tycker jag inte att man i en vy ska använda sig av top överhuvudtaget, detta ska göras i datalagret i den applikation som använder vyn. anledning till detta är att jag vill ha så lite logik och begränsningar som möjligt i databasen.
Citera
2010-10-14, 17:30
  #7
Medlem
Håller med dig helt och hållet fyllenylle. Jag har aldrig stött på en situation där jag behövt eller velat göra vad TS vill göra. Att gå tillbaka och fråga sig varför man vill göra som beskrivet i trådstarten är nog det bästa.

Mitt svar var endast ämnat att besvara TS fråga hur dessa två resultatset kan kombineras till ett.
Citera
2010-10-14, 17:58
  #8
Medlem
så, vad vi egentligen kommit fram till är att hur man än vänder och vrider på sig så är lösningen som TS är ute efter är en dålig lösning

TS: har du tillgång vyns konsument? jag föreslår att du i första hand löser problemet där. om det ändå är så att du vill ha logiken nära databasen så skulle jag föreslå du istället använder dig av en sp istället för vy. då skulle du kunna parametrisera frågan mot databasen på ett helt annat sätt än vad du kan göra när du jobbar med vyer.
Citera
2010-10-14, 19:14
  #9
Medlem
Basers avatar
Hej igen, kul med så många svar

För att besvara er fråga så kan man säkert lösa det på ett bättre sätt om det skulle vara mot en konsument, men nu är det en uppgift jag ska lösa att få resultaten av säljare med mest provision och antal kunder. Utskriften skulle kunna se ut såhär:

Typ Provision/Antal Säljarid Säljare
------------ ---------------------- ----------- -----------------------------------------
Provision 103100 36 Petronella Tillström
Provision 98080 30 Sonja Schreck
Provision 97800 38 Zoe Baum
Provision 84500 37 Zula Lovejoy
Provision 77440 35 Soo Mendoza
Antal Kunder 66 30 Sonja Schreck
Antal Kunder 63 19 Ceola Rockett
Antal Kunder 63 6 Esbjörn Adamnsson
Antal Kunder 61 13 Maria Ahlgren
Antal Kunder 60 17 Ronda Brann
(10 row(s) affected)

Men om jag förstår rätt så är det fortfarande mest logiskt att göra en union av något slag?

/Baser
Citera
2010-10-14, 19:28
  #10
Medlem
kan diskuteras både en och flera gånger. men för att lösa problemet, kör på följande (ungefär)
Kod:
SELECT TOP (5'Provision' as Typdbo.personal.fornamndbo.personal.efternamndbo.personal.personal_id AS Säljaridconvert(float,SUM(dbo.produkt.provision dbo.lonekat.provisionsandel))
AS 
Provision
FROM dbo
.personal INNER JOIN
dbo
.bokning ON dbo.personal.personal_id dbo.bokning.saljare_id INNER JOIN
dbo
.produkt ON dbo.bokning.produkt_id dbo.produkt.produkt_id INNER JOIN
dbo
.lonekat ON dbo.personal.lonekat_id dbo.lonekat.lonekat_id
GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn
ORDER BY Provision DESC

UNION ALL

SELECT TOP 
(5'AntalKunder',  dbo.personal.fornamndbo.personal.efternamndbo.personal.personal_id AS Säljaridconvert(float,COUNT(dbo.bokning.saljare_id dbo.kund.kundansvarig_id))
AS 
Antalkunder
FROM dbo
.bokning INNER JOIN
dbo
.kund ON dbo.bokning.kund_id dbo.kund.kund_id INNER JOIN
dbo
.personal ON dbo.bokning.saljare_id dbo.personal.personal_id AND dbo.kund.kundansvarig_id dbo.personal.personal_id
GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn
ORDER BY Antalkunder DESC 

sen kan jag förtydliga vad jag menade med vyns konsument. det är alltså den som på något sätt använder vyn. t.ex. en applikation.
__________________
Senast redigerad av fyllenylle 2010-10-14 kl. 19:29. Anledning: mixmax
Citera
2010-11-02, 10:16
  #11
Medlem
Basers avatar
Förlåt för att jag är så dålig på det här men när jag använder ovanstående förslag UNION ALL får jag bara felmeddelandet "Incorrect syntax near the keyword 'UNION'.

Hur ska jag använda korrekt syntaxen korrekt?

/Baser
Citera
2010-11-02, 10:49
  #12
Medlem
Citat:
Förlåt för att jag är så dålig på det här men när jag använder ovanstående förslag UNION ALL får jag bara felmeddelandet "Incorrect syntax near the keyword 'UNION'.

Hur ska jag använda korrekt syntaxen korrekt?

hmmm...pröva att ändra till

Kod:
select from (
    
SELECT TOP (5'Provision' as Typdbo.personal.fornamndbo.personal.efternamn,       dbo.personal.personal_id AS Säljaridconvert(float,SUM(dbo.produkt.provision dbo.lonekat.provisionsandel))
    AS 
Provision
    FROM dbo
.personal INNER JOIN
    dbo
.bokning ON dbo.personal.personal_id dbo.bokning.saljare_id INNER JOIN
    dbo
.produkt ON dbo.bokning.produkt_id dbo.produkt.produkt_id INNER JOIN
    dbo
.lonekat ON dbo.personal.lonekat_id dbo.lonekat.lonekat_id
    GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn

    UNION ALL

    SELECT TOP 
(5'AntalKunder',  dbo.personal.fornamndbo.personal.efternamndbo.personal.personal_id AS Säljaridconvert(float,COUNT(dbo.bokning.saljare_id dbo.kund.kundansvarig_id))
    AS 
Antalkunder
    FROM dbo
.bokning INNER JOIN
    dbo
.kund ON dbo.bokning.kund_id dbo.kund.kund_id INNER JOIN
    dbo
.personal ON dbo.bokning.saljare_id dbo.personal.personal_id AND dbo.kund.kundansvarig_id  dbo.personal.personal_id
    GROUP BY dbo
.personal.personal_iddbo.personal.fornamndbo.personal.efternamn
) as a
order by a
.typ desc 
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