I've got a query that runs on a view that contains two modifiedBy dates. I need to return all records where either of these dates falls into a specified range.
From everything I've researched it seems I need something like this:
qbdsCustTableAddressView
.addRange(fieldNum(TCMCustTableAddressView, CustTableModified))
.value(
strFmt("(%1>='%2' AND %1<='%3') || (%4>='%2' AND %4<='%3')",
fieldstr(TCMCustTableAddressView, CustTableModified),
DateTimeUtil::toStr(contract.parmFromDateTime()),
DateTimeUtil::toStr(contract.parmToDateTime()),
fieldstr(TCMCustTableAddressView, EBillModified),
0
)
);
when I compare the resulting query to what is produced by:
qbdsCustTableAddressView
.addRange(fieldNum(TCMCustTableAddressView, CustTableModified))
.value(strFmt("%1..%2", contract.parmFromDateTime(), contract.parmtoDateTime()));
Then the above looks correct by I'm getting a non-specific "Syntax error near 22"
You have a few issues with the parenthesis, single quotation marks and using AND instead of &&.
This should work:
qbdsCustTableAddressView
.addRange(fieldNum(TCMCustTableAddressView, CustTableModified))
.value(
strFmt("(((%1 >= %2) && (%1 <= %3)) || ((%4 >= %2) && (%4 <= %3)))",
fieldstr(TCMCustTableAddressView, CustTableModified),
DateTimeUtil::toStr(contract.parmFromDateTime()),
DateTimeUtil::toStr(contract.parmToDateTime()),
fieldstr(TCMCustTableAddressView, EBillModified),
0
)
);
Try this:
qbdsCustTableAddressView
.addRange(fieldNum(TCMCustTableAddressView, CustTableModified))
.value(SysQuery::range(contract.parmFromDateTime(), contract.parmtoDateTime()));
The difference being SysQuery::range(<from>, <to>)
I don't see an obvious problem, but perhaps that might flush it out for you.
Related
I'm new to progress 4GL. I'm trying to find last record from a table. But its causing performance issue. I directly copied my query here so it should be syntax error. Please help me to modify the logic or give me suggestion.
Note - Syntax(USE-SYNTAX) available only for following fields but not sure adding this to for last is good idea.
pc_domain,
pc_list_classification,
pc_list,
pc_curr,
pc_prod_line,
pc_part,
pc_um,
pc_start
for last pc_mstr no-lock
where pc_domain = global_domain
and pc_list_classification = 1
and pc_curr <> ""
and pc_part = b_ps_mstr.ps_comp
and pc_um <> ""
and (pc_start <= v_end[v_i]
or pc_start = ?)
and (pc_expire >= v_end[v_i]
or pc_expire = ?)
and (pc_amt_type = "L"
or pc_amt_type = "P"):
end.
if not available pc_mstr then
do:
for last pc_mstr no-lock
where pc_domain = global_domain
and pc_list_classification = 1
and pc_curr <> ""
and pc_part = b_ps_mstr.ps_comp
and pc_um <> ""
and (pc_amt_type = "L"
or pc_amt_type = "P"):
end.
end.
What do you mean with last? Do you mean LAST as in what Progress means:
LAST Uses the criteria in the record-phrase to find the last record in the table that meets that criteria. The AVM finds the last record before sorting.
Or do you mean something else? Like the last record created? Depending on what you mean you might have to do different things.
Some pointers about performance though:
Basically where clauses using = is good, >, <, >=, <=, BEGINS etc is decent and <>, NOT is BAD.
But it also boils down to what index you can use. You need to know about the indices of the table! But regardless of indices: those <> will make you unhappy. They will cause "table scans" (the entire table will be read).
<> "" could perhaps be replaced with > "" in this case - a little less evil.
Also you need to use () in a better way with those or's. Otherwise you might not get what you want. OR will win over AND so A AND B OR C really is run as (A AND B) OR C. Maybe you really ment A AND (B OR C) - in that case you need to use those ( ) wisely.
I am using the following measure (and a calendar table) to determine equipment uptime for a given hour of the day based on user input from a datetime slicer:
Selected Hour =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour] = SELECTEDVALUE ( 'CalendarTable'[DateTime] )
)
)
This is working just fine. The problem is that I also need this same calculation performed for each of the 12 hours prior to the selected hour. When I try to use the same formula but with one hour subtracted from the SELECTEDVALUE, like so...
S-1 =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour]
= SELECTEDVALUE ( 'CalendarTable'[DateTime] ) - ( 1 / 24 )
)
)
... I get blank cells in my table visualization, even though I know there is data for that hour:
Why does this happen? Any time I try to perform mathematical operations on the SELECTEDVALUE datetime value, it gives me blanks. But without using operations to manipulate it and just using the selected datetime itself, it works no problem. Is it not possible to subtract an hour from a SELECTEDVALUE datetime? If not, what workaround(s) should I try? (I have also attempted using -TIME(1,0,0) instead of -1/24 but that gave me blanks as well.)
Thanks in advance!!
I think the reason is that the subtraction you are operating isn't convenient to go row by row. Would you please try rather to put it as follows, and put the MAXX() function around the calculus you did, while adding another argument, which is the name of the table in which you want the subtraction to be performed:
S-1 =
CALCULATE (
'UptimeView'[Uptime %],
FILTER (
'UptimeView',
'UptimeView'[LocalShiftDateHour]
= MAXX('Replace_with_Tablename',SELECTEDVALUE(
'CalendarTable'[DateTime] ) - ( 1 / 24 ))
)
)
This is the trick I use. In fact, MAXX(tablename, expression) Evaluates an expression for each row of a table and returns the largest value.
Don't worry about the max, it doesn't have any effect on the result, since the max(one precise value in a precise row)= that same value
Hello there and good morning!
I have a litte problem with the Database of the Time Tracking Software of our company.
The first problem: the time is in a dumb format. If someone works 7h 30m, the database writes 7,30 as value. So far so good. So I have to split the decimals, convert it to industrial time, and put it back together. So far so good. It works, if the value is under 10. Above 10, the value converts itself into INT. But that case should be intercepted by my code.
Here's the code:
SELECT PersNr, Name, CASE WHEN substr(IstStd,3,1) LIKE ',' OR '.' THEN (SUM(CASE WHEN (substr(IstStd,4,2)/60 NOT LIKE 0) THEN ROUND((substr(IstStd,4,2))/60 + (substr(IstStd,1,2)),2) ELSE (IstStd) END)) ELSE (SUM(CASE WHEN (substr(IstStd,3,2)/60 NOT LIKE 0) THEN ROUND((substr(IstStd,3,2))/60 + (substr(IstStd,1,1)),2) ELSE (IstStd) END)) END AS IstStd
FROM ARCHIV_JOURNAL WHERE PersNr ='3041' AND Datum BETWEEN '2019-10-01' AND '2019-10-31'
As you can see in the first CASE, I check if the third character is , or . . The Code works fine, just not for 10h+.
Did I miss something? I'd appreciate any help with that.
If you need more information, just hit me back.
Thank you in advance and have a nice day!
The condition:
WHEN substr(IstStd,3,1) LIKE ',' OR '.'
is not correct.
It is interpreted as:
WHEN (substr(IstStd,3,1) LIKE ',') OR ('.')
If you want to check if the 3d char is ',' or '.' you must do:
WHEN substr(IstStd,3,1) IN (',', '.')
Also in other parts of your code you use the operator LIKE when you should use = or <>.
Change to this:
SELECT PersNr, Name,
CASE
WHEN substr(IstStd,3,1) IN (',', '.')
THEN SUM(
CASE
WHEN (substr(IstStd,4,2)/60 <> 0) THEN ROUND((substr(IstStd,4,2))/60 + (substr(IstStd,1,2)),2)
ELSE (IstStd)
END
)
ELSE SUM(
CASE
WHEN (substr(IstStd,3,2)/60 <> 0) THEN ROUND((substr(IstStd,3,2))/60 + (substr(IstStd,1,1)),2)
ELSE (IstStd)
END
)
END AS IstStd
FROM ARCHIV_JOURNAL
WHERE PersNr ='3041' AND Datum BETWEEN '2019-10-01' AND '2019-10-31'
Also when you divide integers the result is also an integer.
If you want the result of the division:
substr(IstStd,3,2))/60
to be a decimal number, then change it to:
substr(IstStd,3,2))/60.0
I was following this article:
http://msdn.microsoft.com/en-us/library/aa902637%28v=sql.80%29.aspx
and my query for distinct count looks like this:
Count(CrossJoin({[Measures].[Submission Count]}, [Submission].[PK Submission].Members), ExcludeEmpty)
it returns always 1 more than it should (for example it returns 27 instead of 26).
In the same article there is this query (which is suppose to solve this problem):
Count(CrossJoin( {[Sales]},
Descendants([Customers].CurrentMember, [Customer Names])),
ExcludeEmpty)
But I can't get it to work. I've tried these two but second one always returns 1 or 0 while the first one doesn't work (error: I have to explicitly define a level):
Count(CrossJoin( {[Measures].[Submission Count]},
Descendants([Submission].CurrentMember, [Submission].[PK Submission])),
ExcludeEmpty)
Count(CrossJoin( {[Measures].[Submission Count]},
Descendants([Submission].[PK Submission].CurrentMember, [Submission].[PK Submission])),
ExcludeEmpty)
Any idea what am I doing wrong?
Thanks!
The reason the first query returns "1 more than it should" is because the [Submission].[PK Submission].Members tuple set also includes the All member.
If you refer to the [PK Submission] level instead of all the members of the [PK Submission] hierarchy, it doesn't include the All member.
So, the following returns what you're expecting:
Count( CrossJoin( { [Measures].[Submission Count] }
, { [Submission].[PK Submission].[PK Submission] })
, ExcludeEmpty)
I'm creating a music to show notes on Treble and Bass but came to think the staffArray and staffArray2 is true for a given situation.
Such as staffArray and staffArray2 has a value of "1","1","1","1" and "2",2",2",2",2",2"...
When one of the function will identify if the i=0 is 1 then draw note:
if(staffArray[i] == "1" && typeArray[i]=="half" && stemArray[i]=="down") {
drawHalfDown(child,"-","-"); //child is the sprite name
}
Now will draw a note on a staff 2, the above staffArray is still valid and cause the note on staff 2 to be error, how do I rectify these array?
I'm not sure I understand all of what you are trying to do, but your error is probably caused by a typo in your if-clause: The single & is a bitwise, not a logical boolean operator and evaluates to a very different result. If you're interested, you can find out about bitwise AND here.
Your code should be:
if(staffArray[i] == "1" && typeArray[i]=="half" && stemArray[i]=="down") {
drawHalfDown(child,"-","-");
}