Link to home
Start Free TrialLog in
Avatar of Eric Bourland
Eric BourlandFlag for United States of America

asked on

Grouping problem: for every academic degree in one column, there are two certifications displayed in the next

I've been staring at this grouping problem for some time now. I have a directory of Careplanners:

http://careplanners.net/directory.cfm

As you can see, there are repetitions in the Certifications column. The pattern is, for every single academic degree listed, there is an extra certification listed in the next column. Thus, if Susan has earned two degrees -- BA and Diploma Nursing -- then each of her certifications appears twice:

CLCP CCM CLCP CCM

I've tried different ideas in the QUERY and the OUTPUT for a few hours. What am I missing?

Maybe this will make sense to me in the morning. Thanks as always for your help. Eric

QUERY (sorry, this is a huge query, joining five related tables):

<!--- query getCareplanners, select columns from table CareplannersMembers --->
<cfquery datasource="#application.datasource#" name="getCareplanners">
SELECT
<!--- select from parent table, CareplannersMembers cp --->
cp.CareplannersUUID
,cp.CareplannersID
,prefix
,firstname
,middleinit
,lastname
,suffix
,company
,primaryphone
,UserEmail
,website
,street1
,city1
,state1
,zip1
,country1
,phone1
,fax1
,street2
,city2
,state2
,zip2
,country2
,phone2
,fax2
,practice
,info

<!---===== select from child tables and relational tables =====--->
<!--- cdegree = careplanners_degrees --->
<!--- chdegree = careplanners_has_degrees --->
,cdegree.degreeID
,cdegree.DegreeTitle
,chdegree.CareplannersID
,chdegree.degreeID

<!--- ccert = careplanners_certifications --->
<!--- chcert = careplanners_has_certifications --->
,ccert.certificationID
,ccert.certificationTitle
,chcert.CareplannersID
,chcert.certificationID

<!--- cped = careplanners_pediatric --->
<!--- chped = careplanners_has_pediatric --->
,cped.pediatricID
,cped.pediatricTitle
,chped.CareplannersID
,chped.pediatricID

<!--- cadu = careplanners_adult --->
<!--- chadu = careplanners_has_adult --->
,cadu.adultID
,cadu.adultTitle
,chadu.CareplannersID
,chadu.adultID

<!--- creg = careplanners_regions --->
<!--- chreg = careplanners_has_regions --->
,creg.regionID
,creg.region
,chreg.CareplannersID
,chreg.regionID

<!--- select from parent table --->
FROM CareplannersMembers cp

<!--- join the related tables and child tables --->
LEFT OUTER JOIN careplanners_has_degrees chdegree
ON cp.CareplannersID = chdegree.CareplannersID
LEFT OUTER JOIN careplanners_degrees cdegree
ON cdegree.degreeID = chdegree.degreeID

LEFT OUTER JOIN careplanners_has_certifications chcert
ON cp.CareplannersID = chcert.CareplannersID
LEFT OUTER JOIN careplanners_certifications ccert
ON ccert.certificationID = chcert.certificationID

LEFT OUTER JOIN careplanners_has_pediatric chped
ON cp.CareplannersID = chped.CareplannersID
LEFT OUTER JOIN careplanners_pediatric cped
ON cped.pediatricID = chped.pediatricID

LEFT OUTER JOIN careplanners_has_adult chadu
ON cp.CareplannersID = chadu.CareplannersID
LEFT OUTER JOIN careplanners_adult cadu
ON cadu.adultID = chadu.adultID

LEFT OUTER JOIN careplanners_has_regions chreg
ON cp.CareplannersID = chreg.CareplannersID
LEFT OUTER JOIN careplanners_regions creg
ON creg.regionID = chreg.regionID

  ORDER BY
       <cfswitch expression="#sortBy#">  
                <cfcase value="FirstName">FirstName</cfcase>  
                <cfcase value="LastName">LastName</cfcase>
                <cfcase value="city1">city1</cfcase>  
                <cfcase value="practice">practice</cfcase>
                <cfcase value="state1">state1</cfcase>  
                <cfcase value="DegreeTitle">DegreeTitle</cfcase>
                <cfcase value="certificationTitle">certificationTitle</cfcase>
                <cfdefaultcase>cp.CareplannersID</cfdefaultcase>  
           </cfswitch>  
         <cfif url.sortDir eq "DESC">
             DESC
       <cfelse>
             ASC
       </cfif>
  
  </cfquery>




OUTPUT: (I'm leaving in some of the surrounding code so you can see better what is going on)
 <!--- list Careplanners --->
 <cfoutput query="getCareplanners" group="CareplannersID" startRow="#URL.StartRow#" maxRows="#RowsPerPage#">
 
 
 <cfif bgColor neq "##ffffff">
    <cfset bgcolor="##ffffff">
  <cfelse>
    <cfset bgcolor="##f7f5f5">
  </cfif>

  <tr style="background-color:#bgcolor#;">


<td><a style="text-decoration:none !important;" href="/displayCareplanner.cfm?CareplannersID=#getCareplanners.CareplannersID#"><img src="img/smallsearch.gif" width="13" height="13" alt="View" class="border0" /></a></td>

   <td>
   
#getCareplanners.CareplannersID#
   </td>



   
  <!--- FirstName --->
   <td class="left">#getCareplanners.FirstName#</td>
  <!--- LastName --->
   <td class="left">#getCareplanners.LastName#</td>
  <!--- City --->
   <td class="left">#getCareplanners.city1#</td>
  <!--- State --->
   <td class="left">#getCareplanners.state1#</td>
  <!--- Practice --->
   <td class="left">#getCareplanners.practice#</td>
  <!--- Degrees --->
   <td class="left">
<cfoutput group="DegreeTitle" groupcasesensitive="no">
#getCareplanners.DegreeTitle#
</cfoutput> 
   
   </td>
  <!--- Certifications --->
   <td class="left">

<cfoutput group="certificationTitle" groupcasesensitive="no">
#getCareplanners.certificationTitle#
</cfoutput> 

   
   </td>
 


  </tr>
 </cfoutput>

Open in new window

SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Eric Bourland

ASKER

gdemaria,

Godo to hear from you.

When I take away the group from the inner outputs, I get multiple results in degrees and certifications columns:

http://careplanners.net/directory.cfm

So, I think I need to edit my query. I was trying SELECT DISTINCT but that did not help either.

I know there is a way to do this. I'm looking again at the query.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>remember your sql ORDER BY must match the way you're grouping the output.

I remember this, and I noticed the ORDER BY does not match the grouping.

I think I need to give up the dynamic sorting at the top of the page. I'm going to add a search tool anyway.

gd and _agx_, these are very helpful comments as always, and I am thinking about them.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> I would take a different approach

It's role reversal.  lol.  I was going to suggest XML PATH, but wasn't sure if Eric wanted to keep it at the db or CF level.  But FWIW that's what I'd use :)

(Just don't over do it. Having too many XML PATH's in one query can tank performance).
I'm going to try both methods -- mainly, I want to see how each might work.

I gotta switch to another task for a little while then will get back to this Careplanners task. Thank you both. Hope your Monday is going well.
Yep try them out. Either would work, but XML PATH is slicker for smaller queries.
Sorry, I had to take care of a couple of other problems until late last night, and most of today.

This is my simplified query

<!--- query getCareplanners, select columns from table CareplannersMembers --->
<cfquery datasource="#application.datasource#" name="getCareplanners">
SELECT
<!--- select from parent table, CareplannersMembers cp --->
cp.CareplannersUUID
,cp.CareplannersID
,firstname
,lastname
,practice
,city1
,state1
,DegreeTitleList = substring((SELECT ( ', ' + d.DegreeTitle )
                           FROM careplanners_has_degrees hd
                            inner join careplanners_degrees d on hd.degreeID = d.degreeID
                           WHERE hd.CareplannersID = cp.CareplannersID
                           ORDER BY d.DegreeTitle
                           FOR XML PATH( '' )
                          ), 3, 1000 ) 
,certificationTitleList = substring((SELECT ( ', ' + c.certificationTitle )
                           FROM careplanners_has_certifications hc
                            inner join careplanners_certifications c on hc.certificationID = c.certificationID
                           WHERE hc.CareplannersID = cp.CareplannersID
                           ORDER BY c.certificationTitle
                           FOR XML PATH( '' )
                          ), 3, 1000 ) 

FROM CareplannersMembers cp
ORDER BY lastname, DegreeTitle, certificationTitle
  </cfquery>

Open in new window


But I get this error:
Error Executing Database Query.  
[Macromedia][SQLServer JDBC Driver][SQLServer]Invalid column name 'DegreeTitle'.  
The error occurred in C:/websites/www.careplanners.net/directoryTest.cfm: line 24
23 : <!--- query getCareplanners, select columns from table CareplannersMembers --->
24 : <cfquery datasource="#application.datasource#" name="getCareplanners">
25 : SELECT
26 : <!--- select from parent table, CareplannersMembers cp --->

Column DegreeTitle does exist in table careplanners_degrees. I think ColdFusion thinks I am requesting column 'DegreeTitle' from parent table, CareplannersMembers? Hmm. I think I can just add careplanners_degrees in the FROM clause. I will try that. But I wanted to check in here and let you know I am working on this task. =)

Hope your respective days are going well.

Eric
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ah! I see. I get it.

OK, that worked.

Now, ColdFusion says variable DegreeTitle is not defined in the scope of my query, getCareplanners:

Element DEGREETITLE is undefined in GETCAREPLANNERS.
The error occurred in C:/websites/www.careplanners.net/directoryTest.cfm: line 165
163 :    <td class="left">
164 : <cfoutput>
165 : #getCareplanners.DegreeTitle#
166 : </cfoutput>

But when I remove the getCareplanners scope, then the variable DegreeTitle is undefined. How should I define the scope of variable DegreeTitle? (I feel like this should be obvious to me, given all that I have learned here.)

   <td class="left">
<cfoutput>
#getCareplanners.DegreeTitle#
</cfoutput>
   
   </td>
  <!--- Certifications --->
   <td class="left">

<cfoutput>
#getCareplanners.certificationTitle#
</cfoutput>
   </td>
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Holy bananas. That works amazingly well: http://careplanners.net/directory.cfm

And I did not know about the ListChangeDelims function. I just read up on that function at help.adobe.com. That is very useful.

I'm going to come back later and close this question. Great success, and as usual I learned a ton.

Thank you gdemaria and _agx_.

Eric
     >  You can remove the commas and just display with spaces doing this..

Or just use make the delimiter a space to begin with.  Though if you think you'll be using list functions (and the degree title might contain commas or spaces) I'd use a less common delimiter.
     
> That works amazingly well: http://careplanners.net/directory.cfm

Looks good. Though maybe use a line break in between? So the titles don't all run together.
_agx_, good idea. I added a break:

<cfoutput>
#listChangeDelims(getCareplanners.degreeTitleList,"<br />")#
</cfoutput>

And it looks better. I need to format that page to make it more readable.
Yep, much better.
This worked really well. ColdFusion, and gdemaria and _agx_, save the day yet again. I learned some very useful things about ordering data from multiple columns. Thank you as always.

Eric B