OpenJPA/MySQL: modifying a table while the same table is used in the where clause - jpql

I want to execute a delete query via openJPA and mysql.
This mysql statement works fine:
delete from GENERIC
where PARENT_ID not in (select g2.ID from (select * from GENERIC) g2);
The basic element are a table GENERIC with columns ID and PARENT_ID
Mapping the GENERIC table to GenericEntity class, ID column to id member (of that class) and PARENT_ID column to parentId member, I tried this simple test:
entityManager.createQuery("delete from GenericEntity g1 where " +
"g1.parentId not in " +
"(select g2.id from (select * from GenericEntity) g2)"
).executeUpdate();
And I get this error:
org.apache.openjpa.persistence.ArgumentException: "Encountered "g1 .
parentId not in ( select g2 . id from (" at character 36, but
expected: ["(", "*", "+", ",", "-", ".", "/", ":", "<", "<=", "<>",
"=", ">", ">=", "?", "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG",
"BETWEEN", "BOTH", "BY", "CASE", "CLASS", "COALESCE", "CONCAT",
"COUNT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
"DELETE", "DESC", "DISTINCT", "ELSE", "EMPTY", "END", "ENTRY",
"ESCAPE", "EXISTS", "FETCH", "FROM", "GROUP", "HAVING", "IN", "INDEX",
"INNER", "IS", "JOIN", "KEY", "LEADING", "LEFT", "LENGTH", "LIKE",
"LOCATE", "LOWER", "MAX", "MEMBER", "MIN", "MOD", "NEW", "NOT",
"NULL", "NULLIF", "OBJECT", "OF", "OR", "ORDER", "OUTER", "SELECT",
"SET", "SIZE", "SOME", "SQRT", "SUBSTRING", "SUM", "THEN", "TRAILING",
"TRIM", "TYPE", "UPDATE", "UPPER", "VALUE", "WHEN", "WHERE",
, , , ,
, , ,
, ]." while parsing JPQL "delete from
GenericEntity g1 where g1.parentId not in (select g2.id from (select *
from GenericEntity) g2)". See nested stack trace for original parse
error.
I tried different variants, also replaced the delete by an update (to set a 'deleted' flag instead), but it seems to be a general problem to modify a table when this very table is used in the where clause.
I'd appreciate very much a hint, how to continue or a link to any helpful material.
Thank you very much in advance!

After a lot of research, I have found a solution. It works fine to separate the select from the delete query and pass the list of IDs as a parameter to the delete statement:
List<Integer> idList = entityManager
.createQuery("select g.id from GenericEntity g",Integer.class)
.getResultList();
entityManager
.createQuery("delete from GenericEntity g where g.parentId not in (:idList)")
.setParameter("idList", idList)
.executeUpdate();

Related

CosmosDB - list in aggregate query response

I have following document structure:
{
"id": "1",
"aId": "2",
"bId": "3",
....
},
{ "id":"2",
"aId": "2",
"bId": "4"
}
How do i return for that JSON that has aId that has list of all bIds of the same aId, and as additional field: count of such bIds? So for example above and condtion: "WHERE aId="2" response would be:
{
"aId": "2",
"bIds" : ["4","3"],
"bIds count" : 2
}
Assuming i only pass one aId as parameter.
I tried something like:
select
(select 'something') as aId,
(select distinct value c.bId from c where c.aId='something') as bIds
from TableName c
But for love of me i cant figure out how to get that list + its count + hardcoded aId in single JSON response (single row)
For example this query:
select
(select distinct value 'someId') as aId,
(select distinct value c.bId) as bIds
from c where c.aId='someId'
will return
{ { 'aId': 'someId', 'bIds':'2'},{'aId':'someId','bIds':'4'}}
while what i acutally want is
{ {'aId':''someId', 'bIds':['2','4']}}
Here is query that is closest to what i want:
select
c.aId as aId,
count(c2) as bIdCount,
array(select distinct value c2.bId from c2)
from c join (select c.bId from c) as c2
where c.aId = 'SOME_ID'
Only thing line with array make this query fail if i delete this line it works (correctly returns id and count in one row). But i need to select content of this list also, and i ma lost why its not working, example is almost copypasted from "How to perform array projection Cosmos Db"
https://azurelessons.com/array-in-cosmos-db/#How_to_perform_array_projection_Azure_Cosmos_DB
Here is how you'd return an array of bId:
SELECT distinct value c.bId
FROM c
where c.aId = "2"
This yields:
[
"3",
"4"
]
Removing the value keyword:
SELECT distinct c.bId
FROM c
where c.aId = "2"
yields:
[
{ "bId" : "3" },
{ "bId" : "4" }
]
From either of these, you can count the number of array elements returned. If your payload must include count and aId, you'll need to add those to your JSON output.

How to use Join operation/ Subquery in CosmosDB

I have a container in CosmosDB. It contains around 30 variables. CabId is one of the column/variable in that. I want to select duplicate values of CabId and delete those items completely for duplicate CabIds. PartitionKey is another variable in my item.
One item will look like below.
{
"CabId": "8dc2d0f4-d787-4e98-94d0-665a69bfbbf5",
"OS_FlightRing": "*****",
"CPU_FamilyName": "*****",
"Incident_FailureBucketId": "*****",
"Geo_ISOCountryShortCode": "cn",
"OS_Version": "10.0.19042.985",
"PartitionKey": "29997810-1199392862021-10-20"
}
I am using query like this for getting the individual items with duplicate CabId. But I am getting syntax error.
Select * from e JOIN(
SELECT * FROM(
(SELECT c.CabId,Count(c.CabId) AS CabCount
FROM c
where c.PartitionKey = "29997810-1238691972021-10-25"
GROUP BY c.CabId)
d WHERE d.CabCount > 1))
on d.CabId = e.CabId
The below query should give you the duplicates,
Select d.CabId From
(SELECT c.CabId,Count(c.CabId) AS
CabCount FROM c GROUP BY c.CabId) AS d WHERE d.CabCount > 1
{
"CabId": "8dc2d6f4-d787-4e98-94d0-665a69bfbbf5",
"OS_FlightRing": "",
"CPU_FamilyName": "",
"Incident_FailureBucketId": "*****",
"Geo_ISOCountryShortCode": "cn",
"OS_Version": "10.0.19042.985",
"PartitionKey": "29597810-1199392862021-10-20",
"id": "703f5337-4fc2-4d77-acc9-2fbf15900366",
"_rid": "uYFGAPqp2KYCAAAAAAAAAA==",
"_self": "dbs/uYFGAA==/colls/uYFGAPqp2KY=/docs/uYFGAPqp2KYCAAAAAAAAAA==/",
"_etag": ""8c00d214-0000-0700-0000-6172ba160000"",
"_attachments": "attachments/",
"_ts": 1634908694 }
UPDATE:
SELECT count(1) FROM
(SELECT c.CabId ,Count(c.CabId) AS CabCount
FROM c GROUP BY c.CabId,c.PartitionKey) d WHERE d.CabCount > 1

Cosmos DB json array that matchs all the words

I need a query that can get me the document from a list of words for example if I use
select c from c join (SELECT distinct VALUE c.id FROM c JOIN word IN c.words WHERE word in('word1',word2) and tag in('motorcycle')) ORDER BY c._ts desc
it will bring both documents, I want to retrieve only the first one cause it matches the two words and not only one.
Document 1
"c": {
"id": "d0f1723c-0a55-454a-9cf8-3884f2d8d61a",
"words": [
"word1",
"word2",
"word3",
]}
Document 2
"c": {
"id": "d0f1723c-0a55-454a-9cf8-3884f2d8d61a",
"words": [
"word1",
"word4",
"word5",
]}
You should be able to cover this with two ARRAY_CONTAINS expressions in your WHERE clause (and no need for a JOIN):
SELECT c.id FROM c
WHERE ARRAY_CONTAINS(c.words, 'word1')
AND ARRAY_CONTAINS(c.words, 'word2')
This should return the id of your first document.

Outer apply in kusto/ Azure AppInsights

I am new to azure appinsight and kusto, I am trying to write a kusto query that will group items in a table and look for the latest record by time.
This is what i tried so far,
Sample Table:
let Temptable=datatable(RunId:string,Module:string,AppName:string,timestamp:datetime) [
"1", "start", "App1", '2020-02-27T04:30:01.6062658Z',
"1", "end", "App1", '2020-02-27T04:31:01.6062658Z',
"2", "start", "App1", '2020-02-27T04:00:01.6062658Z',
"2", "end", "App1", '2020-02-27T04:01:01.6062658Z',
"3", "start", "App1", '2020-02-27T03:30:01.6062658Z',
"3", "end", "App1", '2020-02-27T03:31:01.6062658Z',
"4", "start", "App1", '2020-02-27T03:00:01.6062658Z',
"4", "end", "App1", '2020-02-27T03:01:01.6062658Z',
"5", "start", "App1", '2020-02-27T02:30:01.6062658Z',
"5", "end", "App1", '2020-02-27T02:31:01.6062658Z',
"6", "start", "App2", '2020-02-27T04:00:01.6062658Z',
"6", "end", "App2", '2020-02-27T04:01:01.6062658Z',
"7", "start", "App2", '2020-02-27T03:00:01.6062658Z',
"7", "end", "App2", '2020-02-27T03:01:01.6062658Z',
"8", "start", "App2", '2020-02-27T02:00:01.6062658Z',
"8", "end", "App2", '2020-02-27T02:01:01.6062658Z',
"9", "start", "App2", '2020-02-27T01:00:01.6062658Z',
"9", "end", "App2", '2020-02-27T01:01:01.6062658Z',
"10", "start", "App2", '2020-02-27T00:30:01.6062658Z',
"10", "end", "App2", '2020-02-27T00:32:01.6062658Z'
];
I am running the below query,
let FactTable = Temptable
| where Module == "start"
| summarize by AppName
| project AppName;
FactTable
| lookup kind = inner (Temptable | partition by AppName( summarize Maxtime = max(timestamp) by AppName | top 1 by Maxtime desc nulls last )) on AppName;
My output:
I need to retrieve all the columns for the latest record.
Below is the query in sql, which will retrieve top 1 record for the particular AppName.
select cs.*
from (select AppName from #TempTable where Module = 'start' group by AppName) a
outer apply (select top 1 * from #TempTable b where b.AppName = a.AppName order by [TimeStamp] desc) cs
How to achieve this in Kusto Query.
Is there anyway to write query in kusto with outer column can be accessible in the subquery,or any other better approach?
Looks like you are looking for arg_max() aggregation function:
For example:
Temptable
| summarize arg_max(timestamp,*) by AppName

Azure Document Query Sub Dictionaries

I have stored the following JSON document in the Azure Document DB:
"JobId": "04e63d1d-2af1-42af-a349-810f55817602",
"JobType": 3,
"
"Properties": [
{
"Key": "Value1",
"Value": "testing1"
},
{
"Key": "Value",
"Value": "testing2"
}
]
When i try to query the document back i can easily perform the
Select f.id,f.Properties, C.Key from f Join C IN f.Properties where C.Key = 'Value1'
However when i try to query:
Select f.id,f.Properties, C.Key from f Join C IN f.Properties where C.Value = 'testing1'
I get an error that the query cannot be computed. I assume this is due to 'VALUE' being a reserved keyword within the query language.
I cannot specify a specific order in the property array because different subclasses can add different property in different orders as they need them.
Anybody any suggestion how i can still complete this query ?
To escape keywords in DocumentDB, you can use the [] syntax. For example, the above query would be:
Select f.id,f.Properties, C.Key from f Join C IN f.Properties where C["Value"] = 'testing1'

Resources