Displaying CFQuery Result Over Time Span - coldfusion

I'm able to get query's over a time span of say 1hr - in 15 minute increments...
I am just trying to stop displaying repetitive result when the Primary Key is the same.
ie: If something starts at 6:45am - and ends at 8:00am - I only want it to span the DIV once if the primary key (masterid) is the same. And then if something else is at 8am with a different primary key - to span that div time frame etc...
I am contemplating a cfloop or the like - checking that the mastered is either the same or different/
Thoughts on how to do this...
Query code working fine - as is my display code... Image included to give idea of what I'm trying to do.
<cfloop index="incr" from="0" to="#loopreps#">
<cfoutput>
Loopreps is thru the time spans of 15 mins...
<cfquery name="scht" datasource="#ds#">
Proper Query
</cfquery>
<cfif scht.recordcount is not 0>
<cfset mid = #scht.masterid#>
This is where I am lost to hold it to only 1 result when spanning time
Proper Display Across Div Height Span once if MasterID is same
</cfif>
</cfoutput>
</cfloop>

As noted in the comments, as a desktop database, MS Access is rather limited. Enterprise databases like SQL Server offer much greater capabilities for tasks like this, such as using CTE's.
However, just to offer another perspective, you could also use an auxiliary table of times, instead. (That was a common approach in SQL Server, prior to the advent of CTE's). You could easily populate a table with fifteen minute increments, between 00:00 to 23:45, using Mark's loop as a basis. Then simply JOIN to that table on the scheduled start and end times. (Access requires the extra parenthesis and derived table).
SELECT ti.IntervalTime
, s.StartTime
, s.EndTime
, s.AppointmentName
FROM TimeInterval ti LEFT JOIN
(
SELECT AppointmentName, StartTime, EndTime
FROM ScheduleTable
WHERE ScheduleDate = <cfqueryparam value="#someDate#" cfsqltype="cf_sql_timestamp">
) s
ON (
ti.IntervalTime >= s.StartTime AND
ti.IntervalTime <= s.EndTime
)
WHERE ti.IntervalTime >= <cfqueryparam value="#fromTime#" cfsqltype="cf_sql_timestamp">
AND ti.IntervalTime <= <cfqueryparam value="#toTime#" cfsqltype="cf_sql_timestamp">
ORDER BY ti.IntervalTime
The result will contain all of the intervals and appointments in one query, no need for looping. You can then output the results however you need.
IntervalTime | StartTime | EndTime | Appointment Name
06:00:00 | | |
06:15:00 | | |
06:30:00 | | |
06:45:00 | 06:45:00 | 08:00:00 | Edge
07:00:00 | 06:45:00 | 08:00:00 | Edge
07:15:00 | 06:45:00 | 08:00:00 | Edge
07:30:00 | 06:45:00 | 08:00:00 | Edge
....

You can loop over time increments directly using the CFLOOP tag. For example this code outputs each 15 minutes. You could combine a loop like this with a check (Q of a Q maybe) to extract availability.
<cfloop index="tm" from="8:00 AM" to="5:00 PM" step="#createTimespan(0,0,15,0)#">
<cfoutput> <li>#TimeFormat( tm, "h:mm TT" )#</li></cfoutput>
</cfloop>
Just keep in mind this is an ok solution for short iterations. If doing long iterations I would set that "step" attribute to a variable rather than calling a function directly. If really long I would probably choose something else. But for a couple days worth of increments it will work perfectly fine I think. See this post on Interesting loop for date and time. Good luck!

I usually put a garbage value before starting a loop.
<cfset CompareValue = "value that will never occur in real life">
<cfloop>
<cfif FieldToCheck is not CompareValue>
<cfset CompareValue = FieldToCheck>
more code
<cfelse>
appropriate code, maybe nothing
</cfif>
</cfloop>

Related

SAS - Comparison of Hours

I'm new to SAS and can't seem to compare hours. Let me explain :
I have a Date/Time (format : ddmmmaa:hh:mm:ss) variable that I reformatted (in format TOD8 : hh:mm:ss) to only have the time.
With this specific time, I want to put it into a time slot. So if the time is between such and such time, I give him a time slot.
The problem that arises for me is that I cannot compare the time. Here is my code:
data test;
set WORK.TABLE;
if 'hour'n > '09:00:00't and 'hour'n < '09:59:59't then 'time slot'n=0910;
else if 'hour'n > '10:00:00't then 'time slot'n=1011;
else 'time slot'n=-1;
run;
This gives me the result :
Hour | time slot
------------------------
08:06:00 | 1011
09:30:00 | 1011
11:00:00 | 1011
I think it comes from the type but I can't find any documentation that allows me to solve this problem.
If you have an idea or something that could help me understand this result it will help me a lot. Thanks in advance
The problem is that you applied a format considering it changed the stored value. That's a wrong statement: a format just applies a "display" pattern, no more.
And this is why you can change the format to what you want without losing any information :)
To extract a time from a datetime, use the timepart function.
Then you'll be able to compare this value against other times:
data test;
set work.table;
attrib extracted_hours format=tod5.;
extracted_hours = timepart(your_datetime);
if '09:00:00't <= extracted_hours < '10:00:00't then 'time slot'n = 0910;
else if '10:00:00't <= extracted_hours < '11:00:0't then 'time slot'n=1011;
else 'time slot'n=-1;
run;

Convert a number column into a time format in Power BI

I'm looking for a way to convert a decimal number into a valid HH:mm:ss format.
I'm importing data from an SQL database.
One of the columns in my database is labelled Actual Start Time.
The values in my database are stored in the following decimal format:
73758 // which translates to 07:27:58
114436 // which translates to 11:44:36
I cannot simply convert this Actual Start Time column into a Time format in my Power BI import as it returns errors for some values, saying it doesn't recognise 73758 as a valid 'time'. It needs to have a leading zero for cases such as 73758.
To combat this, I created a new Text column with the following code to append a leading zero:
Column = FORMAT([Actual Start Time], "000000")
This returns the following results:
073758
114436
-- which is perfect. Exactly what I needed.
I now want to convert these values into a Time.
Simply changing the data type field to Time doesn't do anything, returning:
Cannot convert value '073758' of type Text to type Date.
So I created another column with the following code:
Column 2 = FORMAT(TIME(LEFT([Column], 2), MID([Column], 3, 2), RIGHT([Column], 2)), "HH:mm:ss")
To pass the values 07, 37 and 58 into a TIME format.
This returns the following:
_______________________________________
| Actual Start Date | Column | Column 2 |
|_______________________________________|
| 73758 | 073758 | 07:37:58 |
| 114436 | 114436 | 11:44:36 |
Which is what I wanted but is there any other way of doing this? I want to ideally do it in one step without creating additional columns.
You could use a variable as suggested by Aldert or you can replace Column by the format function:
Time Format = FORMAT(
TIME(
LEFT(FORMAT([Actual Start Time],"000000"),2),
MID(FORMAT([Actual Start Time],"000000"),3,2),
RIGHT([Actual Start Time],2)),
"hh:mm:ss")
Edit:
If you want to do this in Power query, you can create a customer column with the following calculation:
Time.FromText(
if Text.Length([Actual Start Time])=5 then Text.PadStart( [Actual Start Time],6,"0")
else [Actual Start Time])
Once this column is created you can drop the old column, so that you only have one time column in the data. Hope this helps.
I, on purpose show you the concept of variables so you can use this in future with more complex queries.
TimeC =
var timeStr = FORMAT([Actual Start Time], "000000")
return FORMAT(TIME(LEFT([timeStr], 2), MID([timeStr], 3, 2), RIGHT([timeStr], 2)), "HH:mm:ss")

CFCase values with spaces are not found

As anyone had this issue with parsing from html file with setting <cfcase> values that contain spaces in the value? If the value contains spaces ColdFusion isn't able to find the data match in the parsed html file.
For example:
<CFCASE value="LGT RAIN">
<CFSET application.condition="Lt Rain">
</CFCASE>`
The html file has the value "LGT RAIN", but due to the way its being parsed it is not defining the city's condition. Is there a work around like check the condition prior to running your switch statements? Like if "LGT RAIN" is found then set cfset value it to "LGTRAIN".
Here is sample link that I am parsing from.
https://forecast.weather.gov/product.php?site=CAE&issuedby=CAE&product=RWR&format=CI&version=1
<CFSET WeatherData = CFHTTP.FileContent>
Code:
<!--- Check For Condition with Two Word Phrase --------------->
<CFSET condition= #GetToken("#content#",#attributes.citystring# + 1, " ")#>
<br>
<CFSET city = #attributes.citystring#>
<CFIF (condition is "LGT")
or (condition is "HVY")
or (condition is "FRZ")
or (condition is "MIX")
or (condition is "NOT")>
<CFSET condition= (
#GetToken("#content#",#attributes.citystring# + 1, " ")#
& " " &
#GetToken("#content#",#attributes.citystring# + 2, " ")#
)>
<br>
<CFSET Temp = #GetToken("#content#",#attributes.citystring# + 3, " ")#>'
.......
There is a lot of missing context on what you're trying to ultimately do with the weather you get, so I made a couple of assumptions on ways to parse through the weather block.
You'll have to actually parse the page to get that actual block, but once you do, you can use my suggestions below to split those weather elements out. I got rid of the getToken() calls, because I think that may have been more work than you needed, and was essentially led to the problem with spaces. My code is still much wordier than I intended, but I tried to make sure I wasn't using anything above CF8. I think it should all work, but I don't have a CF8 server to test on.
https://trycf.com/gist/1993243eb476a629ec25f8c6e8ddff3c/acf?theme=monokai
I've included some notes inside the code as I went along.
<!--- Create a block of the parsed weather. --->
<cfsavecontent variable="myWX">ANDERSON FAIR 49 16 26 W12G20 30.01F
LIBERTY FAIR 49 14 24 W12G21 29.99F
SPARTANBURG FAIR 45 9 23 NW12G21 30.00F
CLEMSON FAIR 48 10 21 NW13G22 30.02F
GREENVILLE FAIR 48 13 24 VRB3 29.99F
GREENWOOD FAIR 49 13 23 W10G21 30.03F
GREER FAIR 48 9 20 VRB7 29.99F
ROCK HILL FAIR 46 17 31 NW10G22 29.99F
CHESTER FAIR 45 12 26 W12G17 30.01F
LAURENS FAIR 48 16 27 NW12G18 30.01F
</cfsavecontent>
<!--- end of line character (this may change if your feed uses other eol)--->
<cfset crlf = chr(13)&chr(10)>
<!--- Make weather an array of strings for each city. --->
<cfset wxArray = ListToArray(myWX, crlf, false, true)>
My suggestion is to put the different elements in a struct, then work with that. 1 row of city weather = 1 row of Struct.
My code below assumes you are parsing rows of a 65 character fixed-width record from the HTML, which is what it appears to be when you get at the individual rows.
<!--- Loop through the new weather array and make a new array of parsed weather. --->
<!--- Create initial weather array for output. --->
<cfset newWXArray = []>
<cfloop array="#wxArray#" index="wxRow">
<!--- NOTE: Yay go CF8s implicit struct creation! --->
<cfset WXRow = {
city = trim(mid(wxRow,1,15)) , <!--- trim() will remove leading/trailing spaces --->
sky = trim(mid(wxRow,16,10)) ,
tmp = trim(mid(wxRow,26,4)) ,
dp = trim(mid(wxRow,30,4)) ,
rh = trim(mid(wxRow,34,3)) ,
wind = trim(mid(wxRow,37,10)) ,
pres = trim(mid(wxRow,47,6)) ,
rmks = trim(mid(wxRow,53,11))
}>
<!--- ArrayAppend() returns true/false, so this variable isn't used. --->
<cfset throwaway = ArrayAppend(newWXArray, WXRow)>
</cfloop>
<cfdump var="#newWXArray#">
Now you have an array of all the cities, and can pull the individual pieces out for the city you need.
What's the weather like in Liberty? <br>
<cfset whichRow = 0>
<cfloop from="1" to="#arrayLen(newWXArray)#" index="i">
<cfif newWXArray[i].CITY IS "LIBERTY">
<cfset whichRow = i>
</cfif>
</cfloop>
<cfoutput>
City >> #newWXArray[whichRow].CITY# <br>
Sky >> #newWXArray[whichRow].SKY# <br>
Temp >> #newWXArray[whichRow].TMP# <br>
DewPoint >> #newWXArray[whichRow].DP# <br>
Relative Humidity >> #newWXArray[whichRow].RH# <br>
Wind >> #newWXArray[whichRow].WIND# <br>
Pressure >> #newWXArray[whichRow].PRES# <br>
Remarks >> #newWXArray[whichRow].RMKS# <br>
</cfoutput>
Final Note:
I had forgotten how limited CF8 was. There is a lot of stuff you can do to make this MUCH easier if you are able to upgrade to a current version of ACF or Lucee.
Also, as I suggested, changing your link to pull the Text-Only version (https://forecast.weather.gov/product.php?site=CAE&issuedby=CAE&product=RWR&format=txt&version=1&glossary=1) will significantly reduce the amount of text you have to parse through.
My experience with white space in text data messing up conditional logic has been with trailing spaces but the principles are the same. When in doubt look at your data. Here is a simple example:
MyVar = 'Lgt Rain'; // two spaces between the words
if (MyVar == 'Lgt Rain'){ // one space between words
applicable code
}
else {
writeoutput(replace(MyVar, ' ', '-space-', 'all'));
}

search for specific characters within column and then create different columns from it

I have param_Value column that have different values. I need to extract these values and create columns for all of them.
|PARAM_NAME |param_Value |
__________|____________
|Step 4 | SP:0.09 |
|Procedure | MAX:125 |
|Step 4 | SP:Ambient|
|(null) | +/-:N/A |
|Steam | SP:2 |
|Step 3 | MIN:0 |
|Step 4 | RDPHN427B |
|Testing De | N/A |
I only want columns with: And give them names:
SP: SET_POINT_VALUE,
MAX: MAX_LIMIT,
MIN: MIN_LIMIT,
+/-: UPPER_LOWER_LIMIT
So what I have so far is:
CREATE OR REPLACE FORCE VIEW PROCESS_STEPS
("PARAM_NAME", "SET_POINT_VALUE", "UPPER_LOWER_LIMIT", "MAX_VALUE", "MIN_VALUE")
AS
SELECT PARAM_NAME,
REGEXP_LIKE("param_Value", 'SP:') SET_POINT_VALUE,
REGEXP_LIKE("param_Value", '+/-:') UPPER_LOWER_LIMIT,
REGEXP_LIKE("param_Value", 'MAX:') MAX_VALUE,
REGEXP_LIKE("param_Value", 'MIN:') MIN_VALUE
FROM PROCESS_STEPS
;
I'm more familiar with TSQL and MySQL, but this ought to do what I think you're looking for. If it doesn't exactly, it should at least point you in the right direction.
CREATE OR REPLACE FORCE VIEW PROCESS_STEPS
("PARAM_NAME", "SET_POINT_VALUE", "UPPER_LOWER_LIMIT", "MAX_VALUE", "MIN_VALUE")
AS
SELECT PARAM_NAME
, CASE WHEN "param_Value" LIKE 'SP:%'
THEN SUBSTR("param_Value", INSTR("param_Value", ':')+1)
ELSE Null
END SET_POINT_VALUE
, CASE WHEN "param_Value" LIKE '+/-:%'
THEN SUBSTR("param_Value", INSTR("param_Value", ':')+1)
ELSE Null
END UPPER_LOWER_LIMIT
, CASE WHEN "param_Value" LIKE 'MAX:%'
THEN SUBSTR("param_Value", INSTR("param_Value", ':')+1)
ELSE Null
END MAX_VALUE
, CASE WHEN "param_Value" LIKE 'MIN:%'
THEN SUBSTR("param_Value", INSTR("param_Value", ':')+1)
ELSE Null
END MIN_VALUE
FROM PROCESS_STEPS
;
The basic concept here is identifying the information you want via LIKE, then using SUBSTR and INSTR to extract it. While LIKE is normally something to stay away from, since there's no leading % in your case, it's Sargable, and thus probably not a total efficiency sink.
Really, though, I have to ask you to question why you're laying out your data like this - substring operations are slow in any language, and a DB is no exception. Why not use another column for your limit type? Why not lay it out in the view you're currently looking at?

ColdFusion paging and page numbers

I have a list of user comments stored in a database and I'm displaying 10 per page. On page load I need to dynamically render the appropriate amount of page numbers. At first I thought I would just get the total amount of comments and divide that by 10 to get the # of pages. That however doesn't work correctly. For example:
1. 1-10
2. 11-21
3. 22-32
4. 33-43
5. 44-54
6. 55-65
7. 66-76
So basically with my original math if I have 70 results I will have 7 pages, but if I have 71 results I get 8 pages, which obviously isn't correct. How can I fix this?
Here's my original code:
<cfset commentsNumber = getComments.recordcount / 10>
<cfloop from="1" to="#commentsNumber#" index="i" >
<cfoutput>
#i#
</cfoutput>
</cfloop>
Edit: I can't do math today :(
...if I have 71 results I get 8 pages, which obviously isn't correct.
10 results per page w/ 71 results is 8 pages. What's wrong?
If you want to be sure of your record paging in ColdFusion, you could use an open source library like Pagination.cfc. It handles all the math for you and gives you a customizable display.
hey correct you math first.. :) your example is wrong.
If you are showing 10 comments per page then it should be
1. 1-10
2. 11-20
3. 21-30
etc
By the way you can use CFGRID for paging... it's very simple..