InfluxQL: How to Return Boolean if value(x) above or below (y) value? - sql

I have a measurement value(x) that varies between 0 and 500. I would like to use a query to return 1 (Boolean) if this value(x) is below a set value(y) for example 200 and 0 if it is above. I need to do this for a discrete visualization I want to use.
In SQL Server I would use a case expression like
case when col_x < 200 then 1 else 0 end
from <tablename> where <some condition>.
But since Influx has no case expression, I have to use a calculation. In question [52533046][1] it is suggested to use something like
FLOOR(1/(value x/80))
This wont work for example if cpu field is 5. That equation returns 16 so no use as a boolean.

Related

How to compare two strings in an update statement

I am looking to compare two string fields in an update statement. The statement updates the field to 1 if there is a text match and 0 if not. The problem is that say BLPU_TEXT is '55' and then BLPU_PAO_SAO is 'XX55XXX' it is returning 0. But I want it to return 1 if there is any match.
UPDATE NAG_ANALYSIS.AA3_ALL N
SET N.CARTO_BLPU_BLPU_MATCH =
(CASE WHEN N.BLPU_TEXT LIKE '%'||N.BLPU_PAO_SAO||'%'
THEN 1 ELSE 0 END);
Many thanks for your time
Since you're looking for '55' in 'XX55XXX', you need to switch the variables in your WHEN:
from
WHEN N.BLPU_TEXT LIKE '%'||N.BLPU_PAO_SAO||'%'
to
WHEN N.BLPU_PAO_SAO LIKE '%'||N.BLPU_TEXT||'%'
This will turn to WHEN 'XX55XXX' LIKE '%55%'.
It works just like in a regular SQL SELECT [...] WHERE y LIKE z, where the pattern z is searched for in each column y value.

Oracle SQL - If X < 0 Then 0

Sometimes there is a need for returning 0 if the result you obtain is < 0. I would like a simplified, readable, no-redundancy way of doing that. Something to replace and greatly simplify something like:
Select
Case
When Amount_Required - Amount_In_Stock < 0 Then 0
Else Amount_Required - Amount_In_Stock
End as Amount_Needed
After some playing, I think this is a valid method:
Select
Greatest(0, Required - In_Stock) as Needed
Seems fairly readable, especially if it becomes a standard practice. No redundancy of the expression Amount_Needed - Amount_In_Stock. About as short as I think it could possibly be.
Additionally, if you wish to have a # cap, to replace something like:
Case
When X+Y > 9999 Then 9999
Else X+Y
End as Z
you can use a similar method.
Select
Least(9999, Attack - Defense) as Damage --Cap attack damage at 9999
This example doesn't make any sense for a query, but you get the idea.

Alternative to like/ like any?... regexp?

I have a TERADATA dataset that resembles the below:
Customer_ID | Targeting_Region
12 | targ=EU, targ=!Eu.Fr
34 | targ=Asia
56 | targ=!EU
The '!' denotes 'does not equal'. For example, the customer in Row #1 wants to target the EU, but exclude France.
I want to create a field that flags (with a '1') any row where there is 'positive' targeting. By 'positive' targeting I am referring to any row where a specific region as been explicitly INCLUDED ('negative' targeting would be where a region is explicity EXCLUDED, such as the exclusion of France in Row #1). For example, Row #1 contains both positive and negative targeting, Row #2 contains only positive targeting, Row #3 contains only negative targeting.
The problem I am encountering is that a simple case statement won't work (as far as I can tell). I have tried the 2 statements below:
(case when targeting_region like '%targ=%'; then 1 else 0 end) as target_flag
(case when ((targeting_region like '%targ=%';) and (targeting_region not like '%targ=!%';)) then 1 else 0 end) as target_flag
The 1st statement above doesn't work because it will return 1 for both 'targ=' and 'targ=!
The 2nd statement above doesn't work because it will return 1 for rows that ONLY have positive targeting. As such, Row #1 (above) would return a 0 (I want it to return a 1)
Note that that value following 'targ=' could also be a number. E.g., 'targ=12345'
Any ideas on how I could accomplish this? I have heard that teradata has something called regexp but I have been unable to find a good explanation of it after quite a bit of searching.
Thanks!
Maybe not exactly what you're looking for, but if you want a 1 only when there is a positive target and no negative target, then why not make it 0 if there exists a negative target and 1 otherwise?
For example,
case when targeting_region like '%targ=!%' then 0
when targeting_region like '%targ=%' then 1
else null -- Optional if you want to handle when no targeting regions exist
end as target_flag
Would something like this work?
(case when REGEXP_INSTR(targeting_region,'targ=[A-Z,a-z]') = 0; then 0 else 1)
I found syntax and example of REGEXP_INSTR() at
http://www.info.teradata.com/HTMLPubs/DB_TTU_14_00/index.html#page/SQL_Reference/B035_1145_111A/Regular_Expr_Functions.085.03.html#ww14955402
Because there was too little info at this site, you will have to fiddle with it to get it to work.
For example...
The equal sign in "...targ=...", and maybe even the left and right brackets, may need to be escaped, perhaps with backslash. Also, the above assumes that if there is no match, the function returns 0 (rather than NULL). It may need to be changed from "=0" to "IS NULL". Also, I assume that the parameters after the first two are optional. You may need to specify them, e.g., "1,1,i". Also, the expression could be simplified a bit, for example by using a shortcut for [A-Z,a-z], if you can find better documentation.
Explanation:
The second parameter specifies a "pattern" to look for in the first parameter.
1. "targ=" looks for exactly those characters.
2. "[A-Z,a-z]" looks for an alphabetic character. If a "!" occurs, it will not match and the search will proceed with the rest of the string.
3. REGEXP_SUBSTR() returns the character position where the pattern was found in the string. That's overkill because you only want to know yes it was found or no it was not, but hopefully it works because I couldn't find a simpler function.
If I understood you correctly you want 1 if there's any included target regardless of additional excluded regions?
This searches for 'targ=' followed by any other character than '!':
CASE WHEN REGEXP_INSTR(Targeting_Region,'targ=[^!]') = 0 THEN 0 ELSE 1 END
If your release doesn't include REGEXP function there might be OREPLACE:
CASE WHEN POSITION('targ=' IN OREPLACE (Targeting_Region, 'targ=!', '')) > 0 THEN 1 ELSE 0 END

Applying the MIN aggregate function to a BIT field

I want to write the following query:
SELECT ..., MIN(SomeBitField), ...
FROM ...
WHERE ...
GROUP BY ...
The problem is, SQL Server does not like it, when I want to calculate the minimum value of a bit field it returns the error Operand data type bit is invalid for min operator.
I could use the following workaround:
SELECT ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ...
FROM ...
WHERE ...
GROUP BY ...
But, is there something more elegant? (For example, there might be an aggregate function, that I don't know, and that evaluates the logical and of the bit values in a field.)
One option is MIN(SomeBitField+0). It reads well, with less noise (which I would qualify as elegance).
That said, it's more hack-ish than the CASE option. And I don't know anything about speed/efficiency.
Since there are only two options for BIT, just use a case statement:
SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit'
FROM ...
WHERE ...
This has the advantage of:
Not forcing a table scan (indexes on BIT fields pretty much never get used)
Short circuiting TWICE (once for EXISTS and again for the CASE)
It is a little more code to write but it shouldn't be terrible. If you have multiple values to check you could always encapsulate your larger result set (with all the JOIN and FILTER criteria) in a CTE at the beginning of the query, then reference that in the CASE statements.
This query is the best solution:
SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn
FROM MyTable
When you add the BitField+0 it would automatically becomes like int
select min(convert(int, somebitfield))
or if you want to keep result as bit
select convert(bit, min(convert(int, somebitfield)))
Try the following
Note: Min represent And aggregate function , Max represent Or aggregate function
SELECT ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)...
FROM ...
WHERE ...
GROUP BY ...
same result
This small piece of code has always worked with me like a charm:
CONVERT(BIT, MIN(CONVERT(INT, BitField))) as BitField
AVG(CAST(boolean_column AS FLOAT)) OVER(...) AS BOOLEAN_AGGREGATE
Give a fuzzy boolean :
1 indicate that's all True;
0 indicate that's all false;
a value between ]0..1[ indicate partial matching and can be some percentage of truth.

Boolean expression as column value in transact sql

In most RDBMS:es, this work:
select (5 > 3)
and evaluates to true. It doesn't work in MS Transact SQL and the only workaround I've found is to write:
select case when 5 > 3 then 1 else 0 end
Which kind of sucks because it is much more verbose. Is there a better way to write the above kind of checks?
If the problem is arithmetic comparison:
select (5 - 3)
Then at the application level test for < or = or > 0.
You could write it as a scalar-valued function, but it will be very slow on large datasets.
If your program often requires such case constructs you could create your set of functions that will have user functions like Bool_IsGreater(left, right) that will return you your desired 0 or 1.
SQL Server doesn't support boolean value type anyway even for basic column use.
If you will need performance and those 5 and 3 values come naturally from some select query you might want to create a new column and set its value to 1 or 0 by trigger or something, which could help with performance.