View previous topic :: View next topic |
Author |
Message |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 8:09 am Post subject: Comparing counts of rows within individual keys |
|
|
On our database, we have a table that contains vehicles (maximum 6 vehicles per 'policy')
I have a requirement to only list policies that have only motorcycles on them.
Just for the sake of this example, the vehicle table is VEHICLE, and the
vehicle type (motorcycle, passenger vehicle, trailer, etc.) is VEH_TYPE,
and the policy # is POL_NO (POL_NO is the table 'key')
I don't have a problem with doing counts on on entire table, but when it comes to counting and comparing within policies, I'm stuck. Obviously I
need to do a total count of vehicles per policy, then a count of motorcycles per policy, then compare the 2 counts. If they're equal, then
I print out the policy #.
Thanks for any help with this. |
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 8:31 am Post subject: |
|
|
It sounds like you need a GROUP BY and a HAVING. If you determine the motorcycle count and the automobile count for each policy, you'd code something like:
Code: | GROUP BY POLICY
HAVING MOTORCYCLE_CNT > +0
AND AUTOMOBILE_CNT = +0 |
|
|
Back to top |
|
 |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 10:12 am Post subject: |
|
|
Yes, thanks, but that is exactly my problem.... I don't know the code format for capturing 2 separate counts (automobile and motorcycle) on the same policy. |
|
Back to top |
|
 |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 10:25 am Post subject: |
|
|
Thought it might help to show how the table looks.... I only want
to display the POL_NO for policies 2222222 and 4444444 (as they only have motorcycles on them). I would prefer to see all the rows for those policies , but I'd settle for just the unique POL_NO.
Code: | POL_NO VEHICLE_TYPE
1111111 A
1111111 M
2222222 M
2222222 M
3333333 A
3333333 A
3333333 A
4444444 M |
|
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 10:41 am Post subject: |
|
|
You'll need to use a pair of SUM'd columns to generate the counts. Something like this:
Code: | SELECT POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM
WHERE
GROUP BY POL_NO
HAVING M_CNT > +0
AND A_CNT = +0 |
|
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 10:49 am Post subject: |
|
|
Missed the part about selecting all the rows for the motorcycle only policies. You can do that by nesting the SELECT.
Code: | SELECT T_POL_NO
,M_CNT
,<col list>
FROM POL_TBL
INNER JOIN (
SELECT T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM POL_TBL
WHERE <where clause>
GROUP BY POL_NO
HAVING M_CNT > +0
AND A_CNT = +0 ) AS T_POL_TBL
ON POL_NO = T_POL_NO |
|
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 10:53 am Post subject: |
|
|
I see syntax errors, so you can obviously see that this is untested sql. Here's minor corrections:
Code: | SELECT T_POL_NO
,M_CNT
,<col list>
FROM POL_TBL
INNER JOIN (
SELECT POL_NO AS T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM POL_TBL
WHERE <where clause>
GROUP BY POL_NO
HAVING M_CNT > +0
AND A_CNT = +0 ) AS T_POL_TBL
ON POL_NO = T_POL_NO |
|
|
Back to top |
|
 |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 11:17 am Post subject: |
|
|
From your first example, I get the following error:
(POL_SUFFIX is considered the 10th digit of the policy #)
Code: | SELECT POL_NUM
,POL_SUFFIX
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE STATE = '20' AND
GENERAL_STATUS||REASON_GENERAL = '1A'
GROUP BY POL_NUM,
POL_SUFFIX
HAVING M_CNT > +0
AND A_CNT = +0
---------+---------+---------+---------+---------+---------+---------+--------
DSNT408I SQLCODE = -206, ERROR: M_CNT IS NOT A COLUMN OF AN INSERTED TABLE,
UPDATED TABLE, OR ANY TABLE IDENTIFIED IN A FROM CLAUSE, OR IS NOT A
COLUMN OF THE TRIGGERING TABLE OF A TRIGGER |
|
|
Back to top |
|
 |
kolusu Site Admin

Joined: 26 Nov 2002 Posts: 12378 Topics: 75 Location: San Jose
|
Posted: Wed Sep 10, 2008 11:25 am Post subject: |
|
|
tcurrier wrote: | I only want to display the POL_NO for policies 2222222 and 4444444 (as they only have motorcycles on them). I would prefer to see all the rows for those policies , but I'd settle for just the unique POL_NO. |
tcurrier,
Isn't it a simple case of using sub select ? Try this untested sql
Code: |
SELECT *
FROM TABLE
WHERE POL_NO IN (SELECT POL_NO
FROM TABLE
WHERE VEH_TYPE = 'M'
AND POL_NO NOT IN (SELECT POL_NO
FROM TABLE
WHERE VEH_TYPE IN
('A','B','P','R','T')))
|
Hope this helps...
Kolusu |
|
Back to top |
|
 |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 11:41 am Post subject: |
|
|
Kolusu,
I got the following error with your example :
[code:1:8d3efc832e]SELECT *
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE POL_NUM IN (SELECT POL_NUM
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE VEHICLE_TYPE = 'M'
AND POL_NUM NOT IN (SELECT POL_NUM
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE VEHICLE_TYPE |
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 11:57 am Post subject: |
|
|
I don't remember if you can reference the SUM function in the HAVING clause for z/OS. So you have one of two options:
Code: | SELECT T_POL_NO
,M_CNT
,<col list>
FROM POL_TBL
INNER JOIN (
SELECT T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM POL_TBL
WHERE <where clause>
GROUP BY POL_NO
HAVING SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) > +0
AND SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) = +0 ) AS T_POL_TBL
ON POL_NO = T_POL_NO
|
or
Code: |
SELECT T_POL_NO
,M_CNT
,<col list>
FROM POL_TBL
INNER JOIN (
SELECT POL_NO AS T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM POL_TBL
WHERE <where clause>
GROUP BY POL_NO ) AS T_POL_TBL
ON POL_NO = T_POL_NO
AND M_CNT > +0
AND A_CNT = +0 |
|
|
Back to top |
|
 |
tcurrier Intermediate
Joined: 10 Feb 2006 Posts: 188 Topics: 68
|
Posted: Wed Sep 10, 2008 12:01 pm Post subject: |
|
|
Latest attempt: (I added POL_SUFFIX as this is considered part of the policy number)
Code: | SELECT T_POL_NO
,M_CNT
,POL_EFF_DATE
,VEHICLE_TYPE
FROM N090DSNM.H2591DB.TCSAU_VEHI
INNER JOIN (
SELECT POL_NUM||POL_SUFFIX AS T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE STATE = '20'
AND GENERAL_STATUS||REASON_GENERAL = '1A'
GROUP BY POL_NUM||POL_SUFFIX
HAVING M_CNT > +0
AND A_CNT = +0) AS T_POL_TBL
ON POL_NUM||POL_SUFFIX = T_POL_NO
---------+---------+---------+---------+---------+---------+---------+--------
DSNT408I SQLCODE = -206, ERROR: M_CNT IS NOT A COLUMN OF AN INSERTED TABLE,
UPDATED TABLE, OR ANY TABLE IDENTIFIED IN A FROM CLAUSE, OR IS NOT A
COLUMN OF THE TRIGGERING TABLE OF A TRIGGER |
|
|
Back to top |
|
 |
kolusu Site Admin

Joined: 26 Nov 2002 Posts: 12378 Topics: 75 Location: San Jose
|
Posted: Wed Sep 10, 2008 12:56 pm Post subject: |
|
|
tcurrier,
Do you just want to pick policy numbers that ONLY have motorcycle as veh type? if that is the case then try this sql
Code: |
SELECT T_POL_NO
,POL_EFF_DATE
,VEHICLE_TYPE
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE T_POL_NO IN (SELECT T_POL_NO
FROM N090DSNM.H2591DB.TCSAU_VEHI
GROUP BY T_POL_NO
HAVING SUM(CASE WHEN VEHICLE_TYPE = 'M'
THEN 1 ELSE 0 END) >= 1
AND SUM(CASE WHEN VEHICLE_TYPE <> 'M'
THEN 1 ELSE 0 END) = 0)
;
|
Hope this helps...
Cheers
Kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
 |
jsharon1248 Intermediate
Joined: 08 Aug 2007 Posts: 291 Topics: 2 Location: Chicago
|
Posted: Wed Sep 10, 2008 1:22 pm Post subject: |
|
|
For the sql you provided, move the HAVING predicates to the ON clause:
Code: | SELECT T_POL_NO
,M_CNT
,POL_EFF_DATE
,VEHICLE_TYPE
FROM N090DSNM.H2591DB.TCSAU_VEHI
INNER JOIN (
SELECT POL_NUM||POL_SUFFIX AS T_POL_NO
,SUM(CASE WHEN VEHICLE_TYPE = 'M' THEN +1 ELSE +0 END) AS M_CNT
,SUM(CASE WHEN VEHICLE_TYPE = 'A' THEN +1 ELSE +0 END) AS A_CNT
FROM N090DSNM.H2591DB.TCSAU_VEHI
WHERE STATE = '20'
AND GENERAL_STATUS||REASON_GENERAL = '1A'
GROUP BY POL_NUM||POL_SUFFIX
) AS T_POL_TBL
ON POL_NUM||POL_SUFFIX = T_POL_NO
AND M_CNT > +0
AND A_CNT = +0 |
|
|
Back to top |
|
 |
NASCAR9 Intermediate
Joined: 08 Oct 2004 Posts: 274 Topics: 52 Location: California
|
Posted: Wed Sep 10, 2008 1:26 pm Post subject: |
|
|
I would like to see the Explain for both of these queries. _________________ Thanks,
NASCAR9 |
|
Back to top |
|
 |
|
|