ColdFusion cfoutput query group - coldfusion

Please refer to this page:
http://allblacks.01dev.co.nz/templates/super14/textobjects/SRMatchDayList.cfm
Query dump is included there. I've inherited this code and would prefer to work with it if possible.
The following code outputs fixtures by week.
<table cellspacing="0" cellpadding="0" border="0" align="center" width="530">
<tr bgcolor="#797979">
<th align="left"><p> <b>Date</b></p></td>
<th align="left"><p><b>Game</b></p></td>
<th align="left"><p><b>Venue</b></p></td>
<th align="left"><p><b>Time (NZ)</b></p></td>
<th align="center"><p><b>Result</b> </p></td>
</tr>
<cfset iWeekCounter = 0>
<cfif not attributes.useSegmentTitle and attributes.sortDirection is "desc">
<cfset qSegments = oSeries.getSegmentInfo(seriesID=attributes.seriesID)>
<cfset iWeekCounter = qSegments.recordcount + 1>
</cfif>
<cfoutput query="qSeriesEvents" group="segmentID">
<cfif attributes.sortDirection is "desc">
<cfset iWeekCounter = iWeekCounter-1>
<cfelse>
<cfset iWeekCounter = iWeekCounter+1>
</cfif>
<tr>
<td colspan="5"><p><br><strong>
<cfif attributes.useSegmentTitle>
#qSeriesEvents.segment#
<cfelse>
Week #iWeekCounter#
</cfif>
</strong></p></td>
</tr>
<cfoutput>
<cfif textObjectCount gt 0>
<tr>
<td><p> #DateFormat(eventDateTime, "dd mmm")#</p></td>
<td><p>#event#</p></td>
<td><p>#location#</p></td>
<td><p><cfif showTimeField is 1>#lcase(timeFormat(dateadd('h',iTimeOffset,eventDateTime),"h:mm tt"))#</cfif></p></td>
<td align="center" valign="top"><p><cfif isDate(eventDateTime) AND dateDiff("n",eventDateTime, now())>#oEvent.getTeamResult(eventID, homeTeamID)#-#oEvent.getTeamResult(eventID, awayTeamID)#</cfif> </p></td>
</tr>
<tr><td colspan="5"><div style="height:1px; padding:0px; margin0px; font-size:0; border-bottom: 1px solid ##999"></div></td></tr>
</cfif>
</cfoutput>
</cfoutput>
</table>
However, note weeks 3 - 18 in the above URL, which don't have any data. I don't want to display week lines if there is no data. How can I accomplish this using this query output "group=" setup if possible?
SQL from the website
SELECT tObj.textObjectCount, events.*, venues.venue, venues.location, DATENAME(wk, events.eventDateTime - 1) AS EventWeek, s.segment
FROM events join segments s on s.segmentID = events.segmentID
LEFT OUTER JOIN (
SELECT LUTextObjectEvent.eventID, COUNT(*) AS textObjectCount
FROM LUTextObjectEvent
INNER JOIN textObjects ON LUTextObjectEvent.textObjectID = textObjects.textObjectID
GROUP BY LUTextObjectEvent.eventID
) tObj
ON events.eventID = tObj.eventID
LEFT OUTER JOIN venues ON events.venueID = venues.venueID
WHERE (events.eventID IN (
SELECT eventID
FROM events
WHERE segmentID IN (
SELECT segmentID
FROM segments
WHERE seriesID IN (?))
)
)
ORDER BY s.segmentID asc

You're using a LEFT OUTER JOIN which means you'll have one record for every event/segment. Change those to inner joins and you should have your desired results
SELECT tObj.textObjectCount, events.*, venues.venue, venues.location, DATENAME(wk, events.eventDateTime - 1) AS EventWeek, s.segment
FROM events join segments s on s.segmentID = events.segmentID
INNER JOIN (
SELECT LUTextObjectEvent.eventID, COUNT(*) AS textObjectCount
FROM LUTextObjectEvent
INNER JOIN textObjects ON LUTextObjectEvent.textObjectID = textObjects.textObjectID
GROUP BY LUTextObjectEvent.eventID
) tObj
ON events.eventID = tObj.eventID
INNER JOIN JOIN venues ON events.venueID = venues.venueID
WHERE (events.eventID IN (
SELECT eventID
FROM events
WHERE segmentID IN (
SELECT segmentID
FROM segments
WHERE seriesID IN (?))))
ORDER BY s.segmentID asc

Related

How to loop through a SQL query and output individual emails base on

I'm trying to loop over information from a query and send that information in an email. Currently, based on my stored procedure, I'm displaying all the rows in the email.
This is what I'm using to get the above information:
<table>
<thead>
<tr>
<th scope="col" id="left">Admin Name</th>
<th scope="col" id="middle">Department Name</th>
<th scope="col" id="right">Last Logon</th>
</tr>
</thead>
<tbody>
<cfloop query="#inactiveAdmins#">
<tr>
<td class="text-left">#Admin_Name#</td>
<td class="text-left">#Dept_Name#</td>
<td class="">#(Len(Last_Logon) ? dateFormat(Last_Logon, 'mmm dd, yyyy') : 'Never Logged On')#</td>
</tr>
</cfloop>
</tbody>
</table>
This is displaying all Admin Names, All Department Names and all Last Logon.
I need to be able to loop over each department and send an email to each department individually.
To loop over each department, this is what I'm trying, but it's not returning any results. My question is:
Is the syntax correct?
<cfloop query="#ALEmail#">
<cfquery dbtype="query" name="inactiveSW">
SELECT Dept_ID
FROM inactiveSW
WHERE Dept_ID = <cfqueryparam cfsqltype="cf_sql_char" value="#ALEmail.Dept_ID#">
</cfquery>
</cfloop>
This is more of a comment than an answer, but it is long
should be
On this part
<cfquery dbtype="query" name="inactiveSW">
SELECT Dept_ID
FROM inactiveSW
WHERE Dept_ID = <cfqueryparam cfsqltype="cf_sql_char" value="#ALEmail.Dept_ID#">
</cfquery>
Because the FROM is the same as the name=, it is like to either have a syntax error, or overwrite an existing variable.
Besides, you are just selecting a variable that already exists. This doesn't get any new information. Are you trying to test for existence of dept_id?
Lastly, if you are trying to send an email based on a query, it is really straight forward
<cfmail
query="ALEmail"
from="#from#"
to="#to#"
subject="#subject#">
Content here
</cfmail>

CF SQL Creating a Table with different results

I am trying to create a table using coldfusion and sql. The table I am trying to create looks like this:
<cfquery datasource="#application.dsn#" name="someprocessTable">
SELECT *
FROM checklists
</cfquery>
<table id="Checklist_Stats">
<thead>
<th><b>Associate Name</b></th>
<th><b>Location</b></th>
<th><b>Checklists Generated by Associate</b></th>
<th><b>Checklists Generated by Selected Location(s)</b></th>
<th><b>Associate Percentage of Location Total</b></th>
</thead>
<tbody>
<cfoutput query="someprocessTable">
<tr>
<td>#associate#</td>
<td>#location_code#</td>
<td>#associate.recordcount#</td>
<!---<td>##</td>
<td>##</td>--->
</tr>
</cfoutput>
</tbody>
</table>
The part I am unsure about is how do I loop all of this information under one table? Because you would not want to have the same persons name keep reoccurring on the table and then how do you show how many was generated by them since I could not do something like #associate.recordcount#
There seems more than one way to do what you want to achieve like doing a query with joins and groups then dump in table; manage your output with a single CFoutput or use nested CFOutput and/or CFloop.
Following show third approach:
<table border="1" id="Checklist_Stats">
<thead>
<th><b>Associate Name</b></th>
<th><b>Location</b></th>
<th><b>Checklists Generated by Associate</b></th>
<th><b>Checklists Generated by Selected Location(s)</b></th>
<th><b>Associate Percentage of Location Total</b></th>
</thead>
<tbody>
<cfquery name="allAssociatesQry" dbtype="query">
SELECT DISTINCT associate, COUNT(*) AS associateCount FROM someprocessTable GROUP BY associate ORDER BY associate
</cfquery>
<cfloop query="allAssociatesQry">
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT * FROM someprocessTable WHERE associate='#associate#' ORDER BY location_code
</cfquery>
<tr><td><cfoutput>#allLocCodeForAssociateQry.associate#</cfoutput></td>
<cfoutput query="allLocCodeForAssociateQry" group="location_code">
<cfset locCntr = 0 />
<cfoutput>
<cfset locCntr = locCntr + 1 />
</cfoutput>
<cfif allLocCodeForAssociateQry.currentRow NEQ 1>
<tr><td> </td>
</cfif>
<td>#allLocCodeForAssociateQry.location_code#</td>
<td>#allAssociatesQry.associateCount#</td>
<td>#locCntr#</td>
<td>#Round((locCntr/allAssociatesQry.associateCount) * 100)#%</td>
</tr>
</cfoutput>
</cfloop>
</tbody>
</table>
Please note that CF QoQ is case sensitive so if need be then convert associate name and location to lower/upper/title case before hand
A slightly modified code for the CFloop may be like below:
<cfloop query="allAssociatesQry">
<cfset thisAssociateName = trim(allAssociatesQry.associate) />
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT location_code,count(location_code) AS locCntr FROM someprocessTable WHERE associate='#thisAssociateName#' GROUP BY location_code ORDER BY location_code
</cfquery>
<cfoutput query="allLocCodeForAssociateQry">
<tr>
<td>#thisAssociateName#</td>
<td>#allLocCodeForAssociateQry.location_code#</td>
<td>#allAssociatesQry.associateCount#</td>
<td>#allLocCodeForAssociateQry.locCntr#</td>
<td>#Round((allLocCodeForAssociateQry.locCntr/allAssociatesQry.associateCount) * 100)#%</td>
</tr>
<cfset thisAssociateName = "" />
</cfoutput>
</cfloop>

How to Output results based on year from query?

I have a query:
<cfquery name="pivotquery">
SELECT employeedept,cse_name,YEAR,January,February,March,April,May,June,July,August,September,October,November,December
FROM (
SELECT month= datename(month,execoffice_date)
, YEAR =YEAR(execoffice_date)
, employeedept
, COUNT(*) as 'totalstars'
FROM CSEReduxResponses
WHERE execoffice_status = 1
GROUP BY employeedept
, month(execoffice_date)
, YEAR(execoffice_date)
, DATENAME(month,execoffice_date)
)
AS r
JOIN csedept d ON d.cse_dept = r.employeedept
PIVOT
(
SUM(totalStars)
FOR [month] IN (
[January],[February],[March],[April],
[May],[June],[July],[August],
[September],[October],[November],[December]
)
)
AS pvt
</cfquery>
This gets me all the data I want based on the month and year.
I'm outputing the results in a table:
<table >
<thead>
<tr>
<th>Department</th>
<th>January</th>
<th>Frebruary</th>
.........
</tr>
</thead>
<tbody>
<cfoutput query="pivotquery" >
<tr>
<td>#pivotquery.csedept_name#</td>
<td>#pivotquery.January#</td>
<td>#pivotquery.February#</td>
.......
</tr>
</cfoutput>
</tbody>
</table>
Yes is outputting the data correctly. How can I get it to output the results in a separate table by year?
If you take a look at this sqlfiddle, it has 2014 and 2015 data. So I would like generate a separate table for each year. So with the data I created in the sqlfiddle, it would have 2 tables: one for 2014 and 2015.
Depends on how you want things to be displayed. But since it looks like your data is ordered by year then you should be able to display by year via grouping your cfoutput by year. So something like:
<cfoutput query="pivotquery" group="YEAR">
<table >
<thead>
<tr>
<th>Department for #pivotquery.YEAR#</th>
<th>January</th>
<th>Frebruary</th>
.........
</tr>
</thead>
<tbody>
<cfoutput>
<tr>
<td>#pivotquery.csedept_name#</td>
<td>#pivotquery.January#</td>
<td>#pivotquery.February#</td>
.......
</tr>
</cfoutput>
</tbody>
</table>
</cfoutput>

How can I leave the loop if no records are part of the if statement?

Below code works, but I would like to show 'no records' message if
<cfif GetResults2.csedept_id eq aFieldValue> has no records for that value. I have tried to put a counter on, but I just can't get it to show 'no records' and not show the
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead> heading of the table if there are no records.
How can I show "No Records" and hide the table head if the results come back empty
Right now if the result comes back empty it will say "no results"(correct) and display the header(incorrect).
<cfset counter3= 0>
<table cellpadding="0" cellspacing="0" class="tablecolors">
<h2> Comments </h2>
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<tr>
<td nowrap="nowrap">#emp_namefirst# #Left(emp_namelast, 1)# </td>
<td>#Replace(commentpositive, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
<td>#Replace(commentnegative, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
</tr>
<cfelse><p>no records</p>
</cfif>
</cfloop>
</table>
UPDATE: Just to add I do have another query above like #FRANK said that does pretty much the same things for example:
'<cfloop query="GetEmployeeTotals3">
<cfif GetEmployeeTotals3.csedept_id eq aFieldValue> '
here is the query:
select GetResults.* , GetEmployees.emp_namefirst, GetEmployees.emp_namelast
from GetResults, GetEmployees
where employee = emp_id
order by csedept_id
so all the solutions above that I tried won't work.
I would recommend using a query of queries to whittle the result set down to just the values you care about first. Then you can easily check, the recordcount before outputting the table at all.
Alternatively, loop first and build up the results with cfsavecontent, then check to see if you found any prior to getting to the table bits.
Something like this should work. You'll have to set a flag of showRecords that will determine if you should show the headers.
<cfset showRecords = false>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<cfset showRecords = true>
<cfbreak>
</cfif>
</cfloop>
<h2> Comments </h2>
<cfif showRecords>
<table cellpadding="0" cellspacing="0" class="tablecolors">
<thead> <th>Name</th> <th>Positive Comment</th> <th>Negative Comment</th></thead>
<cfloop query="GetResults2">
<cfif GetResults2.csedept_id eq aFieldValue>
<tr>
<td nowrap="nowrap">#emp_namefirst# #Left(emp_namelast, 1)# </td>
<td>#Replace(commentpositive, emp_namefirst, "<B>" & emp_namefirst & "</B>")# </td>
<td>#Replace(commentnegative, emp_namefirst, "<B>" & emp_namefirst & "</B>")#</td>
</tr>
</cfif>
</cfloop>
</table>
<cfelse>
<p>no records</p>
</cfif>
EDIT: Updated answer after question was clarified
You'll need to move your cfif to include your table head when checking for records. If the check comes back with a record count, then output the table head as well as the results, otherwise output "no results". I've written two versions below, one is utilizing the cfoutput instead of a loop (just personal preference) and one with your loop if you wish to keep it.
I added Dan's listfind() valuelist() combo...so give him credit for that.
Edit Edit so this is the super-strength/ultra-correct awesome solution with the 'I-am-tired-of-editing-this-answer-50-times-to-get-OP-an-answer', with bonus shameless theft from Dan's answer above/below. Or where ever we ending up order-wise.
<table>
<cfif getresults2.recordcount AND ListFind(ValueList(GetResults2.csedept_id), aFieldValue)>
<tr>
<th>name</th>
<th>positive comment</th>
<th>negative comment</th>
</tr>
<cfoutput query="getresults2">
<tr>
<td nowrap="nowrap">#emp_namefirst# #left(emp_namelast, 1)# </td>
<td>#replace(commentpositive, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
<td>#replace(commentnegative, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
</tr>
</cfoutput>
<cfelse>
<tr colspan="3">
<td><p>no records</p></td>
</tr>
</cfif>
</table>
If you have your cfoutput somewhere in your code (where we cannot see), then here is your cfloop back, simply replace this where I have the cfoutput in the snippet above.
<cfloop query="getresults2">
<tr>
<td nowrap="nowrap">#emp_namefirst# #left(emp_namelast, 1)# </td>
<td>#replace(commentpositive, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
<td>#replace(commentnegative, emp_namefirst, "<b>" & emp_namefirst & "</b>")#</td>
</tr>
</cfloop>
While your question is still unclear, this might be what you want.
<cfif ListFind(ValueList(GetResults2.csedept_id), aFieldValue)>
your existing code to display results in a table
<cfelse>
<p>No Records Found</p>
Note that this:
ListFind(ValueList(GetResults2.csedept_id), aFieldValue)
will execute and return false even if GetResults2 has no records at all.
Edit starts here
Based on this comment, "well if it only appears on some then display does but to those who do not match then ignore" change your existing code to something like:
<cfquery name = "q3" dbtype = "query">
select * from GetResults2
where csedept_id = #aFieldValue#
<cfquery>
<table>
column header row
<cfoutput query="q3">
data rows
</cfoutput>
<table>
The initial construct at the start of this answer still applies.

cfloop empty query condition?

I have the following ColdFusion code that is getting information from a database and displaying the results on the homepage. Here's the cfquery code:
<cfquery name="getSchedule" datasource="#APPLICATION.datasource#" dbtype="odbc">
SELECT * FROM SCHEDULE_Days SD
LEFT JOIN SCHEDULE_ScheduledClasses SSC ON SD.day_id = SSC.day_id
LEFT JOIN SCHEDULE_Classes SC ON SSC.class_id = SC.class_id
WHERE SD.day_date = #createODBCDate(now())# AND SSC.schedule_cancelled = 0
ORDER BY SSC.start_time
</cfquery>
and the output code:
<cfoutput>
<cfloop query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(start_time,"h:mm tt"))#</td>
<td width="158">#class_name#</td>
</tr>
</cfloop>
</cfoutput>
The issue is, if there is no data contained within getSchedule (i.e., there are no ScheduledClasses), it displays nothing.
I'm looking for a way to change this so that, in the event that there is no data to display, I can specify a message and code to be shown in its absence.
First just a quick CF tip you can make you code better by doing it this way:
<cfif getSchedule.recordcount GT 0>
<cfoutput query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(getSchedule.start_time,"h:mm tt"))#</td>
<td width="158">#getSchedule.class_name#</td>
</tr>
</cfoutput>
<cfelse>
<p>Empty record message here</p>
</cfif>
The reason I put the query output first is most likely this will happen more than with your empty set message.
<cfif getSchedule.recordcount>
.... do something
</cfif>
Will work just aswell there is no need for gt 0
Use the recordCount to detect whether the query has any record
<cfif getSchedule.recordcount gt 0>
.... do something
</cfif>
<cfif getSchedule.RecordCount>
<table>
<cfoutput query="getSchedule">
<tr>
<td width="40"> </td>
<td width="74">#lcase(timeFormat(start_time,"h:mm tt"))#</td>
<td width="158">#class_name#</td>
</tr>
</cfoutput>
</table>
<cfelse>
<p>There are currently no records</p>
</cfif>