Question

We have a territory/salesman relationship where: each Territory (TERR) may have multiple salesman (SALM), but each salesman can have only one territory.

Example:

Territory      Salesman   Sales$ Period   
    1             100      999     1
    1             100      999     2
    1             200      999     1 
    1             200      999     2    
    2             300      999     1
    2             300      999     2
    3             400      999     1
    3             400      999     2

I would like to build a summary table, preferably using a single SQL statement that -

  • shows territory,
  • number of salesmen for this territory (** CLARIFICATION: ** that is total unique salesmen codes that made sales in this territory) and
  • list the salesmen numbers in the same file.

example:

Territory # of Salesmen   Salesman   
--------- -------------   --------   
1             2            100       
1             2            200       
2             1            300       
3             1            400       

SQL:

// First I get a list of territories and number of salesman in each territory
With tmpFile as (Select TERR, SALM, count(*) 
   FROM FILE
   GROUP BY TERR, SALM 
   ORDER BY TERR, SALM   
) 
SELECT tmpFile.TERR, count(*) FROM tmpFile GROUP BY          
tmpFile.TERR ORDER BY tmpFile.TERR

// Next step is to get a list of all salesmen in a territory
Select TERR, SALM
   FROM FILE
   GROUP BY TERR, SALM 
   ORDER BY TERR, SALM
) 

// Final step would be to combine the above two steps. I would like to combine all three steps into a single statement if possible. Is there more effective way to do this. I am using IBM db/2 SQL.

Was it helpful?

Solution

While I would like to use the OLAP version of the statement, my version of DB2 (V6R1) doesn't support the COUNT() function in that context (boohoo). That said, here's a version that does work, and should work on any other RDBMS (I think):

SELECT DISTINCT terr, salm, salesmen
FROM File -- I really hope that's not your file name - it's a reserved word
JOIN (SELECT terr territory, COUNT(DISTINCT salm) salesmen
      FROM File
      GROUP BY terr) Salesmen_Per_Territory
ON territory = terr

Please note the DISTINCT inside COUNT(), as this is what is keeping the salesmen from being counted for each period.

OTHER TIPS

Why not do it in single query?

SELECT Territory, SalesMan, COUNT(*) as [No. of Salesman]
FROM tableName
GROUP BY Territory, SalesMan

Are they on different table? eg, TERR and SALM?

SELECT  a.Territory, b.SalesMan, Count(b.Territory) as [No. of Salesman]
FROM    Terr a 
            INNER JOIN SALM b
                on a.Territory = b.Territory
GROUP BY a.Territory, b.SalesMan

I'd say you are on the right track using a common table expression [aka. WITH clause], but it can easily and efficiently be done in one statement.

WITH t as
(SELECT terr, count(distinct salm) as slspeople
   FROM yourfile
   WHERE salesamt > 0
   GROUP BY terr
)
SELECT DISTINCT s.terr, t.slspeople, s.salm
  FROM yourfile as s
  JOIN    t       using (terr)
  WHERE salesamt > 0
  ORDER BY s.terr, s.salm

The using (terr) clause is a shorthand for on s.terr = t.terr, where the matching columns must have the same name in both tables.

I added the WHERE salesamt > 0 only because one of your clarification requirements was to only list salespeople who had sales. If this is not applicable take this out, of course.


It may be a good idea to take the various answers provided, and analyze them with Visual Explain. This is a valuable tool where you can try different variations, and see what performs better. I use this on IBM i, but I believe it exists on the other two platforms as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top