How to detect if Tabular variable is empty in KQL - kql

I have a dashboard populated with a number of Kusto KQL Queries.
Sometimes, my query below returns zero results (for instance if by miracle, there are no failures in the last 24 hours).
//my dashboard query
let failureResults = exceptions | where blahblahblah;
failureResults;
When there are no items that match the filters, my dashboard is filled with
'The query returned no Results'.
How could I go about checking if this variable is null and then doing a different op? For instance, if it's null, then I would just issue a print "No Failures for today, awesome!"; instead.
I have tried iff() statements and isempty(failures| distinct Outcome) and the like, but to no avail. For example, here is another one which didn't work:
failures | project column_ifexists(tostring(Outcome),"No failures where reported!")

Just thought on an improved solution based on pack_all() and the bag_unpack plugin
let p_threshold = ... ;// set value
let failureResults = datatable(exception_id:int,exception_val:int,exception_text:string)[1,100,"Hello" ,2,200,"World"];
failureResults
| where exception_val > p_threshold
| as t1
| project result = pack_all()
| union kind=outer (print msg = 'No Failures for today, awesome!' | where toscalar(t1 | take 1 | count) == 0 | project result = pack_all())
| evaluate bag_unpack(result)
let p_threshold = 0;
exception_id
exception_text
exception_val
1
Hello
100
2
World
200
let p_threshold = 300;
msg
No Failures for today, awesome!
Fiddle

Well... Kind of...
let p_threshold = ... ;// set value
let failureResults = datatable(exception_id:int,exception_val:int,exception_text:string)[1,100,"Hello" ,2,200,"World"];
failureResults
| where exception_val > p_threshold
| as t1
| union kind=outer (print msg = 'No Failures for today, awesome!' | where toscalar(t1 | take 1 | count) == 0)
| project-reorder msg
let p_threshold = 0;
msg
exception_id
exception_val
exception_text
1
100
Hello
2
200
World
let p_threshold = 300;
msg
exception_id
exception_val
exception_text
No Failures for today, awesome!
Fiddle

Related

KQL :: return only tags with more than 4 records

I have created a Kusto query that allows me to return all our database park. The query only takes 10 lines of code:
Resources
| join kind=inner (
resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscriptionName = name)
on subscriptionId
| where subscriptionName in~ ('Subscription1','Subscription2')
| where type =~ 'microsoft.sql/servers/databases'
| where name != 'master'
| project subscriptionName, resourceGroup, name, type, location,sku.tier, properties.requestedServiceObjectiveName, tags.customerCode
By contract we are supposed to give only 4 Azure SQL Database per customer but sometimes developers take a copy of them and they rename it _old or _backup and suddenly a customer can have 5 or 6 databases.
This increase the overall costs of the Cloud and I would like to have a list of all customers that have more than 4 databases.
In order to do so I can use the tag tags.customerCode which has the 3 letters identifier for each customer.
The code should work like this: if a customer is called ABC and there are 4 Azure SQL Databases with tags.customerCode ABC the query should return nothing. If there are 5 or 6 databases with tags.customerCode ABC the query should return all of them.
Not sure if Kusto can be that flexible.
Here is a possible solution.
It should be noted that Azure resource graph supports only a limited subset of KQL.
resourcecontainers
| where type == 'microsoft.resources/subscriptions'
//and name in~ ('Subscription1','Subscription2')
| project subscriptionId, subscriptionName = name
| join kind=inner
(
resources
| where type =~ 'microsoft.sql/servers/databases'
and name != 'master'
)
on subscriptionId
| project subscriptionId, subscriptionName, resourceGroup, name, type, location
,tier = sku.tier
,requestedServiceObjectiveName = properties.requestedServiceObjectiveName
,customerCode = tostring(tags.customerCode)
| summarize dbs = count(), details = make_list(pack_all()) by customerCode
| where dbs > 4
| mv-expand with_itemindex=db_seq ['details']
| project customerCode
,dbs
,db_seq = db_seq + 1
,subscriptionId = details.subscriptionId
,subscriptionName = details.subscriptionName
,resourceGroup = details.resourceGroup
,name = details.name
,type = details.type
,location = details.location
,tier = details.tier
,requestedServiceObjectiveName = details.requestedServiceObjectiveName

Force an Azure Resource Graoh to show 0 - KQL - Azure monitor

I want to create a pie chart showing the counts of open (not closed) alerts which is working. However, I want it to default to 0 in the chart when there is no alert for a particular severity
alertsmanagementresources
|extend Sev = tostring(parse_json(properties.essentials.severity)),
LastModifiedTime = todatetime(properties.essentials.lastModifiedDateTime)
| where tostring(parse_json(properties.essentials.alertState)) <> 'Closed'
| where resourceGroup =='ai-eazyfuel-eu-prd-rg'
| where Sev =='Sev0'
|where LastModifiedTime >=datetime(2022/07/26)
|summarize count() by Sev
Is this even possible because I understand there are no results to show but you know what end users are like
While it's feasible to write the KQL query:
Azure Resource Graph uses only a limited subset of KQL which makes the query syntax cumbersome.
Azure Resource Graph cannot display 0 size slice.
P.S.
Please note the removal of unnecessary transformations of properties and the use of ISO format for datetime.
resources
| take 1
| mv-expand severity = range(0,4) to typeof(string)
| project severity = strcat("Sev", severity)
| join kind=leftouter
(
alertsmanagementresources
| extend severity = tostring(properties.essentials.severity)
,lastModifiedDateTime = todatetime(properties.essentials.lastModifiedDateTime)
| where properties.essentials.alertState <> "Closed"
and resourceGroup == "ai-eazyfuel-eu-prd-rg"
and severity == "Sev0"
and lastModifiedDateTime >= datetime("2022-07-26")
| summarize count() by severity
) on severity
| project severity, count_ = coalesce(count_, 0)

PIG : How to print only certain attributes from Grouped Bag

I have a grouped result which looks exactly like below :
| grouped | group:chararray | log:bag{:tuple(driverId:chararray,truckId:chararray,eventTime:chararray,eventType:chararray,longitude:chararray,latitude:chararray,eventKey:chararray,CorrelationId:chararray,driverName:chararray,routeId:chararray,routeName:chararray,eventDate:chararray)}
When I perform below :
x = FOREACH grouped GENERATE {log.driverId, log.truckId, log.driverName};
illustrate x;
The out put am getting is :
| x | :bag{:tuple(:bag{:tuple(driverId:chararray)})} |
------------------------------------------------------------------------------------
| | {({(11), (11)}), ({(74), (39)}), ({(Jamie Engesser), (Jamie Engesser)})} |
------------------------------------------------------------------------------------
Where as my expectation is :
{({(11, 74, Jamie Engesser), (11,39,Jamie Engesser)})
Got the Solutions
Since
Group was a tuple and The adjacent result was Bag i had to use Nested FOREACH like below :
x = FOREACH grouped{
val1 = group;
vals = FOREACH log GENERATE driverId, truckId, driverName;
GENERATE val1, vals;
};
So this selected only the required attributes from the given result.
Please comment if some one knows a better/optimal/easier way of doing it.
Thanks

SQL Compare on 1st or 2nd value pair

I need to build a query which will compare off one of two value pairs in my table, my table structure looks something like this:
product_id | psi_a | gpm_a | psi_b | gpm_b |
-------------------------------------------------------------
PRODUCT_123 | 1000 | 400 | 8000 | 300 |
-------------------------------------------------------------
PRODUCT_456 | 2804 | 3006 | 5800 | 579 |
When my psi_a and gpm_a are a value pair as are psi_b and gpm_b, I currently have to run two SQL querys to get the values I require to render my site page correctly, however this results in two sets of results being appended to the page.
Markup
$flowQ = $function->flow_query( $pType, $pVal, $gVal, $class_style, $cVal, $pageCat );
$highQ = $function->high_query( $pType, $pVal, $gVal, $class_style, $cVal, $pageCat );
if(empty($flowQ)===false){
$function->generate_view( $flowQ, $pType, $pVal, $gVal, $class_style, $cVal, $pageCat );
}
The current SQL built by these functions are as follow:
flow_query();
$query = $this->db->prepare( "SELECT * FROM `pumps` WHERE `pump_type` = ? AND `psi_a` >= ? AND gpm_a >= ? AND `pump_category` = ? ORDER BY pump_type DESC" );
$query->bindValue(1, $pType);
$query->bindValue(2, $pVal);
$query->bindValue(3, $gVal);
$query->bindValue(4, $cVal);
The second query is pretty much identical, but it uses psi_a and gpm_a as value parameters. Is there any way to combine these querys to return a single result set that will reference psi_a and gpm_a, and if that returns no results then it references psi_b and gpm_b?
I am relatively novice to SQL so if this is not possible then I shall seek an alternative solution.
May as well call it an answer. You can use and / or clauses in you where statement.
where (psi_a = ? and gpm_a = ? ) or (psi_b = ? and gpm_b = ? )
You can also put a case clause in the select statement that will show you which where clause found the match if it's needed.

MySQL change a value depending on its original value

Hy everyone,
Long time reader, first time poster.
This sounds like it should be really simple but I can't find the solution anywhere. I'm building a ratings system where people can rate if something is active or not. It has its own little logic but for it to work I need to.
check the items rating
depending on the current rating change it to a pre set amount.
I could hard code it in PHP with two SQL statements but I'm sure using a single stored procedure (one for vote up, another for vote down) will be much faster.
example table:
item_id | item_rating
---------------------
10 | 1
logic to vote item_rating up:
if | then
---------
0 | 1
1 | 2
-1 | 1
-2 | 1
2 | 2
logic to vote item_rating down:
if | then
---------
0 | -1
1 | -1
-1 | -2
-2 | -2
2 | -1
I know a simple points based system would be easier but due to the nature of the system this is the simplest solution I could find.
Can someone explain how I would use IF statements in SQL to achieve this? I'm sure the answer is really obvious to someone in the know.
(btw using the latest version of MySQL)
Is this what you're looking for? Here's an upvote:
UPDATE rating
SET item_rating = IF(item_rating < 1, 1, 2);
Here's a downvote:
UPDATE rating
SET item_rating = IF(item_rating > -1, -1, -2);
This is untested, but I think it should work.
update items i
set item_rating = (select i.item_rating + `then` from item_rating
where `if` = i.item_rating)
where i.item_id = 10