current_principal_is_member_of gives syntax error - azure-data-explorer

I am trying to use the following
datatable (Brand:string, Country:string, Store:string)
[
'brand1', 'SE', 'Store1',
'brand2', 'SE', 'Store2'
]
| distinct Brand, Country, Store
| order by Brand, Country, Store
| extend _groupToCheck = strcat(Brand, "-",tolower(Country), "-store-", tolower(Store))
| extend _isValidStore = current_principal_is_member_of(_groupToCheck)
But I am getting a syntax error on the _isValidStore = ....
The error os as follows:
current_principal_is_member_of: argument #1 must be a constant string or constant dynamic array of string literals with up to 64 elements
I tried using mv_expand etc but I cannot seem to get it in the correct format
How can I format the _groupToCheck value so its accepted by the current_principal_is_member_of?
I wanted the final result to be
Brand, Country, Store, isValidStore
Brand1 SE Store1 1
Brand2 SE Store2 0
Depending on the result for the ad call

Related

table counterpart of column_ifexists()

We do have a function column_ifexists() which refers to a certain column if it exists, otherwise it refers to another option if we provide. Is there a similar function for table? I want to refer to a table and run some logic against it in the query , if the table exists , but if it doesn't exist, there shouldn't be a failure -- it should simply return no data.
e.g.
table_ifexists('sometable') | ...<logic>...
Please note that the fields referenced in the query should be defined in the dummy table, otherwise in case of non-existing table, the query will yield an exception
Failed to resolve scalar expression named '...'
In the following example these fields are StartTime, EndTime & EventType
Table exists
let requested_table = "StormEvents";
let dummy_table = datatable (StartTime:datetime, EndTime:datetime, EventType:string)[];
union isfuzzy=true table(requested_table), dummy_table
| where EndTime - StartTime > 30d
| summarize count() by EventType
EventType
count_
Drought
1635
Flood
20
Heat
14
Wildfire
4
Fiddle
Table does not exist
let requested_table = "StormEventsXXX";
let dummy_table = datatable (StartTime:datetime, EndTime:datetime, EventType:string)[];
union isfuzzy=true table(requested_table), dummy_table
| where EndTime - StartTime > 30d
| summarize count() by EventType
EventType
count_
Fiddle

Kusto Query, How to Save Query Result and Use Later

In App Insight, how can I write a KQL that save a query result into a variable, and use that variable later in a second query?
For example, find the timestamp when an incident happens:
let incidentTime = traces
| where message = "UNIQUE IDENTIFIER"
| limit 1
Later use this timestamp in a 2nd query to find nearby traces when incident happens
traces
| where timestamp between (datetime_diff('minute', -1, incidentTime)..incidentTime)
The second query gives me an error basically saying cannot retrieve the scalar value from incidentTime.
How can I read the value from incidentTime and put it into the 2nd query?
you can use toscalar() and around():
https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/toscalarfunction
https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/around-function
for example:
let incidentTime = toscalar(
traces
| where message = "UNIQUE IDENTIFIER"
| project timestamp
| limit 1
);
traces
| where around(timestamp, incidentTime, 1m)
similarly, if you want to do so for multiple columns:
let params = toscalar(
traces
| where message = "UNIQUE IDENTIFIER"
| project pack_array(timestamp, username)
| limit 1
);
traces
| where around(timestamp, todatetime(params[0]), 1m)
| where username == tostring(params[1])

Kusto result column name, bin value from request_parameters

Using query_parameters, how can I:
specify a result column name (ex: summarize ResultColumnName = count())
specify the value of a bin, when value is actually the name of a column in the table
This is easiest to summarize with an example:
let myTable = datatable (Timestamp:datetime)
[datetime(1910-06-11),
datetime(1930-01-01),
datetime(1997-06-25),
datetime(1997-06-25)];
let UntrustedUserInput_ColumnName = "MyCount"; // actually from query_parameters
let UntrustedUserInput_BinValue = "Timestamp"; // actually from query_parameters
let UntrustedUserInput_BinRoundTo = "365d"; // actually from query_parameters
// the query I really want to perform
myTable
| summarize MyCount=count() by bin(todatetime(Timestamp), totimespan(365d));
// what the query looks like if I use query_parameters
myTable
| summarize UntrustedUserInput_ColumnName=count() by bin(todatetime(UntrustedUserInput_BinValue), totimespan(UntrustedUserInput_BinRoundTo));
Results:
Timestamp MyCount
--------- -------
1909-09-26T00:00:00Z 1
1929-09-21T00:00:00Z 1
1996-09-04T00:00:00Z 2
Column1 UntrustedUserInput_ColumnName
------- -----------------------------
4
I can't find a solution to #1.
It appears #2 can almost be solved by using column_ifexists, but I don't have a "default" to fall back on, I'd rather just fail if the column doesn't exist.
Treating column names as variables is not possible since columns names are part of the result schema coming out of each operator (with the exception of the "evaluate" operator, see specifically the pivot plugin).
There actually is a way to set variable names to a column, using a hacky trick:
let VariableColumnName = "TestColumn"; // the new column name that you want
range i from 1 to 5 step 1 // this is just a sample query
| project pack(VariableColumnName, i) // this created a JSON
| evaluate bag_unpack(Column1) // unpacking the JSON creates a column with a dynamic name
This will return a column named TestColumn, which is set in VariableColumnName.

Sorting special characters specially?

I have a tablename contacts which has columns [ "id","name","age" ].I need to get all the contacts order by name in ascending order.I wrote the following query for it:
Select * from contacts order by name collate nocase asc;
The results I get from the above above query are following:
1. 11 | #ax Nene | 21
1. 21 | 123 Ray | 22
1. 33 | maxy Wel | 25
1. 41 | Max Vele | 23
1. 53 | Nam sing | 25
The above ordering is fine but I want names starting with special characters [#,$ or any other non-alphabet] to be at the bottom in the results rather than at top.What should I modify in my query to achieve the desired results.
NOTE: I am using sqlite.
You have to prepend some character like ~ (which is sorted after letters) to any such string.
When you do this only in the ORDER BY clause, it affects only the sorting and not the returned values:
SELECT *
FROM contacts
ORDER BY CASE WHEN name GLOB '[A-Za-z]*'
THEN name
ELSE '~' || name
END COLLATE NOCASE;
(COLLATE NOCASE makes the sorting case-insensitive.)

Dynamic query based on second table

I have a table of price quotes for multiple symbols
Table QUOTES
ID INT
SYMBOL NVARCHAR(6)
DT DATETIME
PRICE DECIMAL(18,5)
Table TempSymbol
SYMBOL NVARCHAR(6)
I want to extract only those symbols from QUOTES whose symbols are also in a temp table that could vary based on user request
Create TABLE TempSymbol
(
SYMBOL NVARCHAR(6) NOT NULL
);
INSERT INTO TempSymbol(SYMBOL) VALUES ('MSFT');
INSERT INTO TempSymbol(SYMBOL) VALUES ('INTC');
INSERT INTO TempSymbol(SYMBOL) VALUES ('AAPL');
I want a query that will return from QUOTES the following data...
datetime symbol1 | price1 | symbol2 | price2 | symbol3 | price3
2012-11-12 12:10:00 MSFT | 12.10 | INTC | 5.68 | AAPL | 16.89
2012-11-12 12:15:00 MSFT | 12.22 | INTC | 5.97 | AAPL | 16.22
....
...
..
SELECT DT, SYMBOL, PRICE FROM QUOTE AS Q INNER JOIN TempSymbol AS TS ON Q.SYMBOL = TS.SYMBOL
This returns records that I need to pivot but that's not available in SQLite is there an another way I should be attempting this? Any help is appreciated.
try out this
SELECT DT, SYMBOL, PRICE FROM QUOTE where SYMBOL in (Select SYMBOL from TempSymbol)
SQL is doing the part of your problem that it's designed to do: retrieve the data. You can add ORDER BY DT to make the records for the same date-time adjacent.
If you think about it a minute you'll see that a SELECT can't possibly return what you want. It returns table rows, and SQL table rows have constant length. So doing what you call a "pivot" is not a SELECT operation. You may be thinking of pivots in spreadsheets. Databases aren't spreadsheets.
After that, producing the report you want is best done with a little program in any of the languages with an SQLite interface (in Android for example that's Java; otherwise C or TCL). Make the query. Get the rows back as hashes, arrays, or ODM records. The rest is a couple of loops over this data. The algorithm is:
last_dt = null
for row in all rows
if row.dt != last_dt
start new output line
print dt
last_dt = dt
end
print ' | ', row.symbol, ' | ', row.price
end
Another note: With advanced DB features like stored procedures and XML objects you could implement this in SQL. XML objects can have variable numbers of fields. Here the limit is SQLite, which doesn't provide these features.

Resources