CFIF Stucture refuses to work. Always uses first statement - coldfusion

Sorry the above is a little vague it's rather hard to word. I've got a simple CFIF statement in my code to set datesup to be either "st", "nd", "rd" or "th" as appropriate.However, when the code is run, it just sets datesup to be "st" and nothing else.
Code is below.
#DATEFORMAT(date, "dddd")# the #DATEFORMAT(date, "dd")#
<cfset dateday = #DATEFORMAT(date,"dd")#>
<cfif dateday eq 01 OR 21 OR 31>
<cfset datesup = "st">
<cfelseif dateday IS 01 OR 11>
<cfset datesup = "nd">
<cfelseif dateday IS 03 OR 23>
<cfset datesup = "rd">
<cfelse>
<cfset daatesup = "th">
</cfif>
#datesup# of #DATEFORMAT(date, "mmmm, yyyy")#

You can't do...
cfif dateday eq 01 OR 21 OR 31
It should be...
cfif dateday eq 01 OR dateday eq 21 OR dateday eq 31
All the numbers are evaluated as true so just doing OR 21 is the same as doing OR true.
Also, ColdFusion provides a Day(now()) function you can use rather than dateformat.

Your expression means:
if ( dateday == 01 ) or ( 21 ) or ( 31 )
Since 21 and 31 convert to true, the condition is true.
You need
if dateday eq 01 or dateday eq 21 or dateday eq 31
Or
if listFind( '01,21,31', dateday )

The OR 21 is evaluating to true. You'd need to change it to -> <cfif dateday eq 01 OR dateday eq 21 or dateday eq 31>
You could also use <cfif right( dateday , 1 ) eq 1>
The variable for "th" should be datesup, you have an extra a there.

Related

DATASET IS NOT AN OBJECT,how do i go about this error

what's wrong with my code?
69 data train2.sacked;
70 train2.payrise;
71 set train2.exam (drop = test1 test2 test3 test4);
72 mean2 = mean(test1, test2, test3, test4);
73 if mean2 > 5 then
74 do
75 result = 'PASS'
76 action = 'Pay rise'
77 output payrise;
78
79 if mean2 <= 5 then
80 do
81 result = 'LOSER'
82 action = 'SACKED'
83 output sacked;
84
85 else do
86 result = 'What have I done?'
87 action = 'PARTY'
88 output aahhhhh;
89 length lname fname $ 40 result $ 20;
90 run;
I try running the code but it gives me the error.
ERROR: DATA STEP Component Object failure. Aborted during the COMPILATION phase.
ERROR 557-185: Variable train2 is not an object.
The error is from the second statement.
train2.payrise;
SAS thinks you are trying to reference a method of an object named TRAIN2 but the data step has not defined such an object (an example of an object in a data step is a HASH). I suspect that you meant that to be a dataset to include on the DATA statement but there is an extra semicolon in the middle of the DATA statement.
The rest of your program also has a lot of errors.
You are missing a lot of semicolons at the end of statements.
Your OUTPUT statements are trying to write to datasets not listed on the DATA statement.
You are trying to take the MEAN() of variables that you specifically told SAS to NOT load.
You are trying to set the length of character variables at the end of the data step. So either the variables existed and their length was already set so this attempt to change the length will fail. Or the variables will be created with all missing values since there is not code to assign them any values.
Here's the start of mistakes in your code. This will get you moving forward though I suspect you have more issues in your code.
semicolon to early - this semicolon is unnecssary and limits your output to one data set
Drop variables test1 to test4 which you attempt to use in the next step
Attempt to use dropped variables
Missing semicolon
Missing END
69 data train2.sacked; /*1*/
70 train2.payrise;
71 set train2.exam (drop = test1 test2 test3 test4); /*2*/
72 mean2 = mean(test1, test2, test3, test4); /*3*/
73 if mean2 > 5 then
74 do /*4*/
75 result = 'PASS' /*4*/
76 action = 'Pay rise' /*4*/
77 output payrise;
78 /*5*/
79 if mean2 <= 5 then
80 do /*4*/
81 result = 'LOSER' /*4*/
82 action = 'SACKED' /*4*/
83 output sacked;
84 /*5*/
85 else do /*4*/
86 result = 'What have I done?' /*4*/
87 action = 'PARTY' /*4*/
88 output aahhhhh;
/*5*/
89 length lname fname $ 40 result $ 20;
90 run;

Redshift AWS - Update table with lag() in sub query and cte

I have a Redshift database with the following entries:
table name = subscribers
time_at
calc_subscribers
calc_unsubscribers
current_subscribers
2021-07-02 07:30:00
0
0
0
2021-07-02 07:45:00
39
8
0
2021-07-02 08:00:00
69
17
0
2021-07-02 08:15:00
67
21
0
2021-07-02 08:30:00
48
23
0
The goal is to calculate current_subscribers with the previous value.
current_subscribers = calc_subscribers - calc_unsubscribers + previous_current_subscribers
I do the following:
UPDATE subscribers sa
SET current_subscribers = COALESCE( sa.calc_subscribers - sa.calc_unsubscribers + sub.previous_current_subscribers,0)
FROM (
SELECT
time_at,
LAG(current_subscribers, 1) OVER
(ORDER BY time_at desc) previous_current_subscribers
FROM subscribers
) sub
WHERE sa.time_at = sub.time_at
The problem is that in the sub query "sub" a table is generated that is based on the current values in the table, and thus previous_current_subscribers is always 0. Instead of going through this row by row. So the result is: current_subscribers = calc_subscribers - calc_unsubscribers + 0 I have also already tried it with CTE, unfortunately without success:
The result should look like this:
time_at
calc_subscribers
calc_unsubscribers
current_subscribers
2021-07-02 07:30:00
0
0
0
2021-07-02 07:45:00
39
8
31
2021-07-02 08:00:00
69
17
83
2021-07-02 08:15:00
67
21
129
2021-07-02 08:30:00
48
95
82
I am grateful for any ideas.
The problem you are running into is that you want to use the result of one row in the calculation of the current row. This is recursive which I think you can do in this case but is expensive.
The result you are looking for is the sum of all calc_subscribers for this row and previous rows minus the sum of all calc_unsubscribers for this row and previous rows. This is the difference between 2 window functions - sum over.
sum(calc_subscribers) over (order by time_at desc rows unbounded preceding) - sum(calc_unsubscribers) over (order by time_at desc rows unbounded preceding) as current_subscribers

Oracle REGEX to format value to time

I have the following code in Oracle to retrieve a value formatted as a DateTime:
E.EVE_START_DATE || ' ' || LPAD(NVL(TRIM(SUBSTR(AGD_START_TIME, 0, LENGTH(AGD_START_TIME)-2)), '00') || ':' || NVL(SUBSTR(AGD_START_TIME, -2), '00') || ':00', 8, '0') EVE_START_DATE
The AGD_STARTTIME column has it's data stored in this format:
930
1330
1630
1730
I have been trying to rewrite this using a Regex but having issues.
E.EVE_START_DATE || ' ' || regexp_replace('0'||AGD_START_TIME,'.*([0-9]{2})([0-9]{2})$','\1:\2:00') EVE_START_DATE
But, I'm ending up with this returned data, why would only the 930 entry be messed up?
08-JUN-16 16:30:00
05-OCT-16 0 930
05-OCT-16 13:30:00
22-JUN-16 16:30:00
13-JUL-16 0 930
13-JUL-16 13:30:00
10-AUG-16 16:30:00
18-MAY-16 13:30:00
21-SEP-16 13:30:00
02-NOV-16 17:30:00
22-JUN-16 16:30:00
22-JUN-16 13:30:00
14-SEP-16 0 930
12-OCT-16 17:30:00
20-OCT-16 17:30:00
10-AUG-16 13:30:00
You nailed it 95% I think.
You just a extra space in front of 930. TRIM() should solve it!
E.EVE_START_DATE || ' ' || regexp_replace('0'||TRIM(AGD_START_TIME),'.*([0-9]{2})([0-9]{2})$','\1:\2:00') EVE_START_DATE
Sample:
SQL> with my_data(AGD_START_TIME) as
2 (
3 select ' 930' from dual
4 union all
5 select '1330' from dual
6 union all
7 select '1630' from dual
8 union all
select '1730' from dual
9 10 )
11 select regexp_replace('0'||TRIM(AGD_START_TIME),'.*([0-9]{2})([0-9]{2})$','\1:\2:00') as str
from my_data; 12
STR
--------------------------------------------------------------------------------
09:30:00
13:30:00
16:30:00
17:30:00

CTE Query Not Returning Desired Results

I'm not getting the first record below returned in my CTE query (shown later):
Here's my table:
Key ParentID ChildID (Removed DateJoined Field here)
1 0 1
3 1 83
4 1 84
6 83 85
7 85 86
8 83 87
My CTE Query produces the following results:
ID Name Date Joined Parent ID Parent Name Level
83 Hanks, James 2014-09-13 1 Golko, Richard 1
84 Hanks, James 2014-09-13 1 Golko, Richard 1
85 Walker, Jamie 2014-09-13 83 Hanks, James 2
87 Newman, Betty 2014-09-20 83 Hanks, James 2
86 Adams, Ken 2014-09-13 85 Walker, Jamie 3
How can i also return the first record with ParentID = 0?
When I call the following sproc like this:
EXEC UCU_RTG_ProgramStructure_GetMemberTree 0,4
I still only get results starting with parentID=1 as shown above
Here's my CTE Query:
CREATE PROCEDURE [dbo].[UCU_RTG_ProgramStructure_GetMemberTree]
#ParentID int,
#MaxLevel int
AS
WITH matrix
AS
(
--initialization
SELECT UserID, DateJoined, ParentID, 1 AS lvl
FROM dbo.UCU_RTG_ProgramStructure
WHERE ParentID = #ParentID
UNION ALL
--recursive execution
SELECT p.UserID,p.DateJoined,p.ParentID, lvl+1
FROM dbo.UCU_RTG_ProgramStructure p INNER JOIN matrix m
ON p.ParentID = m.UserID
WHERE lvl < #MaxLevel
)
SELECT matrix.UserID, u.LastName + ', ' + u.FirstName AS Member ,DateJoined,ParentID,u2.LastName + ', ' + u2.FirstName AS Parent,lvl
FROM matrix
INNER JOIN dbo.Users u
ON u.UserID = matrix.UserID
INNER JOIN dbo.Users u2
ON u2.UserID = matrix.ParentID
ORDER BY ParentID
THE CTE Query is fine except it doesn't return the parentID=0 record(s)
Thanks...
I figured it out finally after looking at my post to make sure it was correct: the final select clause is wrong:
SELECT matrix.UserID, u.LastName + ', ' + u.FirstName AS Member ,DateJoined,ParentID,u2.LastName + ', ' + u2.FirstName AS Parent,lvl
FROM matrix
INNER JOIN dbo.Users u
ON u.UserID = matrix.UserID
INNER JOIN dbo.Users u2
ON u2.UserID = matrix.ParentID
the last INNER JOIN has to be changed to LEFT JOIN because there is no UserID 0 to join the ParentID 0 to.
Hope this helps someone else with recursive CTE queries.

How to split array of strings (string [])?

I have got array of strings
string [] foo
array consist next data:
2014 01 02 234 124
2014 01 03 640 710
2014 01 04 234 921
I need new array of strings date, that would include only date (yyyy-MM-dd). How can I do it?
Here's a functional approach:
string[] dates = foo.map!(line => line.split()[0..3].join("-")).array();
If you know that your dates always are yyyy MM dd than just slice the string.
translate is in std.string
dchar[dchar] translateTable = [' ' : '-'];
auto dates = foo.map!(line => translate(line[0..10], translateTable));