ColdFusion - Displaying rows as columns - coldfusion

I'm building a scorecard with ColdFusion which will allow for updating data. I need to display the data with the rows as columns and columns as rows. Here is an example of the table:
Mon Met1 Met2 Met3 Met2 Met5
Jan 15 24 21 40 50
Feb 30 21 14 39 44
Mar 15 19 20 28 19
Apr 16 31 33 21 43
I want to display the data (flipping the rows and columns) like this:
Metric Jan Feb Mar Apr
Met1 15 30 15 16
Met2 24 21 19 31
Met3 21 14 20 33
Met4 40 39 28 21
Met5 50 44 19 43
Any help would be appreciated.
Thanks

Sounds like a 'vertical sorting' FAQ I wrote years ago. Perhaps this will help:
<html>
<head>
<title>Vertical Sorting</title>
</head>
<cfquery name = "qMyQuery" datasource = "dsn">
SELECT fields
FROM table
ORDER BY myField
</cfquery>
<body>
<!--- set the number of colums you wish to have --->
<cfset cols = 5>
<!--- get the number of rows so you know what record to display at the top of the next row. for example if our query contains "a,b,c,d,e,f,g,h,i,j,k,l,m" (13 elements) it will produce 3 totalrows--->
<cfset totalRows = ceiling(qMyQuery.RecordCount / cols)>
<!--- set inital record to 1 "output" is the actual cell of the query --->
<cfset output = 1>
<!--- Create table --->
<table width = "100%" border="0" align="center" cellpadding="2" cellspacing = "2">
<!--- loop through the rows. This loop will run 3 times in this example --->
<cfloop from = "1" to = "#totalRows#" index = "thisRow">
<tr>
<!--- this loop will run 5 times in times in this example --->
<cfloop from = "1" to = "#cols#" index = "thisCol">
<!--- the width in the table cell will dynamicaly calculated to evenly distribute the cells. in this example if cols = 5 100/5 will make the cells 20% of the table --->
<td width = "<cfoutput>#numberformat((100/cols), 99)#</cfoutput>%" align="center" nowrap style = "border: 1px solid #ccc;">
<!--- Check current record with the record count, this will be used to display data or an empty cell --->
<cfif output lte qMyQuery.recordCount>
<cfoutput>#qMyQuery.Mon[output]#</cfoutput>
<cfelse>
<!--- use <br> to display an empty cell --->
<br>
</cfif>
<!--- increment counter to the next record in this example if we started on the first cell of the first row it would be 1(a), then 4(d), then 7(g) and so on if this was the firs cell on the second row it would be 2(b), 5(e), 8(h), continue... --->
<cfset output = output + totalRows>
</td>
</cfloop>
<!--- this little bit tells where to start the next row. if we just finished the first row output would be 2(b) --->
<cfset output = thisRow + 1>
</tr>
</cfloop>
</table>
</body>
</html>

Related

How to output query value only once?

I have query that returns four columns. One of the columns can have the same value for multiple records. I would like to output that value only once. Here is example of the data:
Rec ID Name Color Year
45 Nick Green 2018
34 Mike Red 2018
37 Nick Blue 2019
44 John Pink 2019
23 Jimmy Orange 2019
I uses this code to output the values:
<cfoutput>
<cfloop query="myQuery">
<cfif fiscal_year gt 1991>
<tr>
<td colspan="4"><a href="new_page.cfm?year=#year#>View All</a></td>
</tr>
</cfif>
<tr>
<td>#rec_id#</td>
<td>#name#</td>
<td>#color#</td>
<td>#year#</td>
</tr>
</cfloop>
</cfoutput>
My output looks like this:
View All
45 Nick Green 2018
View All
34 Mike Red 2018
View All
37 Nick Blue 2019
View All
44 John Pink 2019
View All
23 Jimmy Orange 2019
Instead I would like my output too look like this:
View All
45 Nick Green 2018
34 Mike Red 2018
View All
37 Nick Blue 2019
44 John Pink 2019
23 Jimmy Orange 2019
What is the easiest way to achieve this?
The <cfoutput> tag has a group attribute that allows you to group your query data by a column. You can nest the grouped data in another <cfoutput> tag and even group by multiple columns. It should look something like this:
<cfoutput query="myQuery" group="year">
<cfif fiscal_year gt 1991>
<tr>
<td colspan="4">View All</td>
</tr>
</cfif>
<cfoutput>
<tr>
<td>#rec_id#</td>
<td>#name#</td>
<td>#color#</td>
<td>#year#</td>
</tr>
</cfoutput>
</cfoutput>

Select median value per time range

I need to select a median value for each id, in each age range. So in the following table, for id = 1, in age_range of 6 months, I need to select value for row 2. Basically, I need to create a column per id where only median for each range is selected.
id wt age_range
1 22 6
1 23 6
1 24 6
2 25 12
2 24 12
2 44 18
If I understand correctly, you're looking to make a new column where for each id and age_range you have the median value for comparison. You could do this in base SAS by using proc means to output the medians and then merge it back to the original dataset. However proc sql will do this all in one step and to easily name your new column.
proc sql data;
create table want as
select id, wt, age_range, median(wt) as median_wt
from have
group by id, age_range;
quit;
id wt age_range median_wt
1 24 6 23
1 22 6 23
1 23 6 23
2 24 12 24.5
2 25 12 24.5
2 44 18 44

How to loop through .txt file

I need help reading in a .txt file one line at a time. This is the text file for winning Powerball numbers:
Draw Date WB1 WB2 WB3 WB4 WB5 PB PP
08/27/2016 48 32 63 04 49 20 2
08/24/2016 25 11 09 65 64 16 3
I would like to read in one line at a time. The closest I got was:
<cfloop file="http://www.powerball.com/powerball/winnums-text.txt" index="chars" characters="23">
<cfoutput>#chars#</cfoutput>
<br>
</cfloop>
The output was this:
Draw Date WB1 WB2 WB3
WB4 WB5 PB PP 08/27/
2016 48 32 63 04 4
This make each 23 characters a line, which is incorrect. Also, I don't know how to get rid of the header.
Draw Date WB1 WB2 WB3 WB4 WB5 PB PP
Thank you for your time.
You need something to identify you're on the first row to not output it. Also, drop the characters="23" so the loop is based on a line breaks within the file.
<cfset outputRow = false>
<cfoutput>
<cfloop file="http://www.powerball.com/powerball/winnums-text.txt" index="chars">
<cfif outputRow>
#chars#<br>
<cfelse>
<cfset outputRow = true>
</cfif>
</cfloop>
</cfoutput>

Cfloop inside cfloop? [duplicate]

This question already has an answer here:
Why my cfloop stop after inserting first id?
(1 answer)
Closed 7 years ago.
I have a question about my cfloop inside of another cfloop. Here is my code:
<cfloop from="1" to="5" index="k">
<cfloop from="#qry.S#" to="#qry.E#" index="i" step="#CreateTimeSpan(0,0,qry.Leng,0)#">
<cfset TimeEnd = dateAdd("n", Leng, i)>
<tr>
<td>(#k#) #timeFormat(TimeStart, "hh:mm tt")# - #timeFormat(TimeEnd, "hh:mm tt")#</td>
</tr>
<cfset TimeStart = dateAdd("n", qry.Leng, i)>
</cfloop>
</cfloop>
This code above gives me output like this:
09:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
*10:00 AM - 09:15 AM
09:15 AM - 09:30 AM
09:30 AM - 09:45 AM
09:45 AM - 10:00 AM
As you can see I put the star next to the line where my code gives me wrong values. For some reason my start time after first loop is done once, starts from the end time. Can anyone tell me how this can be fixed?
You can't use "i" as the index for both the outer and inner loop. Use something else for the inner loop (x). For example:
<cfloop from="1" to="5" index="i">
<cfloop from="#qry.S#" to="#qry.E#" index="x" step="#CreateTimeSpan(0,0,qry.Leng,0)#">
<cfset TimeEnd = dateAdd("n", Leng, i)>
<tr>
<td> #timeFormat(TimeStart, "hh:mm tt")# - #timeFormat(TimeEnd, "hh:mm tt")#</td>
</tr>
<cfset TimeStart = dateAdd("n", qry.Leng, i)>
</cfloop>
</cfloop>
I'm not sure of the intention here so you may need to swap some of you i's for x's in the inner loop depending on what you are after (start-end for example).
*************************** edits ****************
Maybe I see your issue (not sure) but based on your comment your issue is going to be that you have reset the timestart var. You need to do that after your first loop begins.
<cfloop> outer loop
<Cfset timestart = *starting value*>
<cfloop> inner looop
Other wise your timestart is going to be whatever your last cfset for it was - in the inner loop.

How to output table results by using cfoutput group by date?

I have a query that get the all the employees count in a table:
emp_namelast | emp_namefirst | employeetotal | year_cse1
--------------------------------------------------------
smith | john | 13 | 2014
smith jr | jonnny | 10 |2014
baker |jane |5 |2015
doe |john |6 |2015
I'm outputting the results in a table. I have the results in order from the query.
But with the code below it's outputting the top result from 2014 and then the top
result from 2015.
I have tried using no group , which gives me all the data from the query.
I would like it to output the data from 2014 and 2015 in two different tables.
One would contain records for 2014 and the other 2015.
Would it have to be done without using a 'group'?
<h2>employees</h2>
<table >
<thead><tr><th>Employee</th><th>Stars</th></tr></thead>
<tbody>
<cfoutput query="GetEmployeeTotals" group="year_cse1">
<tr><td>#emp_namefirst# #emp_namelast#</td>
<td>#employeetotal#</td>
</tr>
</cfoutput>
</tbody>
</table>
You are on the right track but are missing a detail. The group attribute works like this:
<cfoutput query="somequery" group="somefield">
grouped data goes here
<cfoutput>
ungrouped data goes here
</cfoutput>
grouped data can go here as well
</cfoutput>
In your code, you are not outputting any grouped data, and you are missing the extra cfoutput tags for the ungrouped data.