January 4, 2010 at 5:14 am
I have a table “CompetencyImportanceData“, which includes the fields JobID, ConstructNo, ImportanceScoreBand, and ImportanceTypeID. For each JobID, the table contains ImportanceScoreBand values for 20 Constructs (ConstructNo – numbers range from 9 to 28).
JobIdConstructNoImportanceScoreBandImportanceTypeID
1931
11021
11121
11211
11321
11421
11521
11641
ImportanceTypeID is a foreign key to the table “ImportanceLevelBands”. This table stores information on which ImportanceBands are associated with each ImportanceTypeID. In my current use of the “CompetencyImportanceData“ table, ImportanceTypeID is “1” for all JobIDs, which means that the ImportanceScoreBand values range from 1 to 4. However, in other use cases, I will have different ImportanceTypeIDs, which means the ImportanceScoreBand values could for example range from 1 to 10.
ImportanceTypeIDImportanceBands
11
12
13
14
For each of the 20 constructs, I need to count the number of jobs that have ImportanceScoreBand values of the ImportanceTypeID (i.e., in this case values 1, 2, 3, and 4). It is important that I also include the cases where the count is 0. So, the resultset needs to include the columns ConstructNo (9-28), ImportanceScoreBand (1-4), and count of number of jobs for the ConstructNo/ImportanceScoreBand. Here is an extract of the resultset I am looking for:
ConstructNoImportanceScoreBandCount
917
9215
9334
940
10124
10254
1030
104102
So far, I have used the query below to get me nearly what I need – it provides the correct count of each ImportanceScoreband by ConstructNo. The problem is that I cannot find out how to return a count of zero when there are no jobs for the Construct/ImportanceScoreBand. I select JobID, ConstructNo, and ImportanceScoreBand from CompetencyImportanceData into a derived table. Then I join the derived table on the ImportanceLevelBands table, and group on dt.ConstructNo, dt.ImportanceScoreBand, and ImportanceLevelBands.ImportanceBands, and do a count of dt.JobID.
I hoped joining in the “ImportanceLevelBands“ table to the derived table would do the trick, but it doesn’t work (right outer join or right join also don’t work).
select dt.ConstructNo, ILB.ImportanceBands, COUNT(dt.JobID) NumJobs
from
(select top 100 percent CID.JobID, CID.ConstructNo, CID.ImportanceScoreBand
from CompetencyImportanceData CID
group by CID.JobID, CID.ConstructNo, CID.ImportanceScoreBand
order by CID.ConstructNo)
AS dt
inner join ImportanceLevelBands ILB
on dt.ImportanceScoreBand = ILB.ImportanceBands
group by dt.ConstructNo, dt.ImportanceScoreBand, ILB.ImportanceBands
order by dt.ConstructNo, dt.ImportanceScoreBand
Any help much appreciated!
January 4, 2010 at 5:35 am
Hi Steven
Please modify the code below to provide sufficient sample data to return your required result set.
-- Set up test data
-- “CompetencyImportanceData“
-- For each JobID, the table contains ImportanceScoreBand values for 20 Constructs
-- (ConstructNo – numbers range from 9 to 28).
CREATE TABLE #CompetencyImportanceData (JobId INT, ConstructNo INT, ImportanceScoreBand INT, ImportanceTypeID INT)
INSERT INTO #CompetencyImportanceData (JobId, ConstructNo, ImportanceScoreBand, ImportanceTypeID)
SELECT 1, 9, 3, 1 UNION ALL
SELECT 1, 10, 2, 1 UNION ALL
SELECT 1, 11, 2, 1 UNION ALL
SELECT 1, 12, 1, 1 UNION ALL
SELECT 1, 13, 2, 1 UNION ALL
SELECT 1, 14, 2, 1 UNION ALL
SELECT 1, 15, 2, 1 UNION ALL
SELECT 1, 16, 4, 1
-- ImportanceTypeID is a foreign key to the table “ImportanceLevelBands”.
-- This table stores information on which ImportanceBands are associated with each ImportanceTypeID.
-- In my current use of the “CompetencyImportanceData“ table, ImportanceTypeID is “1” for all JobIDs,
-- which means that the ImportanceScoreBand values range from 1 to 4.
-- However, in other use cases, I will have different ImportanceTypeIDs,
-- which means the ImportanceScoreBand values could for example range from 1 to 10.
CREATE TABLE #ImportanceLevelBands (ImportanceTypeID INT, ImportanceBands INT)
INSERT INTO #ImportanceLevelBands (ImportanceTypeID, ImportanceBands)
SELECT 1, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 1, 3 UNION ALL
SELECT 1, 4
SELECT c.*, '#', i.*
FROM #CompetencyImportanceData c
INNER JOIN #ImportanceLevelBands i ON i.ImportanceTypeID = c.ImportanceTypeID
-- 32 rows as expected
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
January 4, 2010 at 6:01 am
January 4, 2010 at 6:09 am
SwePeso (1/4/2010)
Also see
Nice answer, Peso.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
January 4, 2010 at 6:29 am
Thank you. I thought I should post the link so that no more double unneccessary work is done.
I suggested your approach first, but after som clarifications, I saw that OP meant something else.
So instead of posting same solution, again, I posted the link to my suggestion.
N 56°04'39.16"
E 12°55'05.25"
January 4, 2010 at 6:30 am
Well, I have some time left...
SELECTc.ConstructNo,
b.ImportanceBands,
COUNT(cib.ConstructNo) AS [Count]
FROM(
SELECTConstructNo
FROMCompetencyImportanceData
GROUP BYConstructNo
) AS c
CROSS JOIN(
SELECTImportanceBands
FROMImportanceLevelBands
GROUP BYImportanceBands
) AS b
LEFT JOINCompetencyImportanceData AS cib ON cib.ConstructNo = c.ConstructNo
AND cib.ImportanceScoreBand = b.ImportanceBands
GROUP BYc.ConstructNo,
b.ImportanceBands
N 56°04'39.16"
E 12°55'05.25"
January 4, 2010 at 6:37 am
SwePeso (1/4/2010)
Thank you. I thought I should post the link so that no more double unneccessary work is done.I suggested your approach first, but after som clarifications, I saw that OP meant something else.
So instead of posting same solution, again, I posted the link to my suggestion.
Something doesn't quite add up in the OP's requirements description. I'd wager a few pesos that you've nobbled it.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
January 4, 2010 at 8:25 am
Chris, Peso - Thanks very much for your help and input.
Chris - I have attached a file with some insert statements to add example data that matches what I'm working with - I had this more easily to hand, but let me know if you find it easier to work with example data in the format you suggested.
Peso - your suggestion looks very promising. However, I can't quite get it to work. I get this error message:
"Column 'c.ConstructNo' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
January 4, 2010 at 8:39 am
See the GROUP BY part above. I added it now.
N 56°04'39.16"
E 12°55'05.25"
January 4, 2010 at 8:47 am
Tremendous - worked perfectly! 🙂
Thanks very much indeed!
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply