Empty group by and nested construct - group-by

I have two questions regarding (i) group by clauses and (ii) nested construct SPARQL queries.
(i) Is it possible to formulate a SPARQL query with an empty GROUP BY clause
i.e. something like GROUP BY (), where the keyword "GROUP BY" appears in the query with an empty set of values.
(ii) Could a nested query be a "CONSTRUCT SPARQL query", the results of which will be then used in an outer SELECT clause, i.e.
SELECT
WHERE {
{
CONSTRUCT ...
}
}

Related

How to use select syntax for group by field which is array in Dynamics AX

I have field Value in table finStatementTrans which is array.
How should I write select syntax with group by and sum by this field?
while select finStatementTable join DataClassParagraph,sum(Value) from finStatementTrans
group by finStatementTrans.DataClassParagraph
where finStatementTable.RecId == finStatementTrans.FinStatementTable_FK
&& finStatementTable.FinStatementTableParent_FK == 5637569094
{
info(strFmt(%1,%2",finStatementTrans.DataClassParagraph,finStatementTrans.Value[1]));
}
Is this correct?
sum(Value[1])
with this I can't compile.
As Aliaksandr Maksimau mentioned in his comment, aggregating array fields is not possible. Aggregations are only supported for integer and real data type fields.
See also X++ data selection and manipulation, paragraph select statements, last sentence.

Using CTE (WITH queries) in Laravel query builder

In a project, I'm using a Common Table Expression (CTE) in Postgres for a recursive expression on a table. The recursive expression figures out all child rows under a parent.
I'm using the Laravel framework with query builder to write this query. I would like to avoid raw queries. I am looking for a way to chain the CTE in the query builder syntax, but I end up with a raw query (DB::select('raw query here')).
Is there a way that I can chain the CTE part? Like below in pseudo code:
DB::statement('WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
UNION ALL
SELECT p.sub_part, p.part, p.quantity
FROM included_parts pr, parts p
WHERE p.part = pr.sub_part')
->select('subpart')
->table('included_parts')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->etc etc more query expressions
I've created a package for common table expressions: https://github.com/staudenmeir/laravel-cte
$query = 'SELECT sub_part, part, quantity FROM parts [...]';
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]
You can also provide a query builder instance:
$query = DB::table('parts')
->where('part', 'our_product')
->unionAll(
DB::query()->[...]
)
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]

How to use postgresql any with jsonb data

Related
see this question
Question
I have a postgresql table that has a column of type jsonb. the json data looks like this
{
"personal":{
"gender":"male",
"contact":{
"home":{
"email":"ceo#home.me",
"phone_number":"5551234"
},
"work":{
"email":"ceo#work.id",
"phone_number":"5551111"
}
},
..
"nationality":"Martian",
..
},
"employment":{
"title":"Chief Executive Officer",
"benefits":[
"Insurance A",
"Company Car"
],
..
}
}
This query works perfectly well
select employees->'personal'->'contact'->'work'->>'email'
from employees
where employees->'personal'->>'nationality' in ('Martian','Terran')
I would like to fetch all employees who have benefits of type Insurance A OR Insurance B, this ugly query works:
select employees->'personal'->'contact'->'work'->>'email'
from employees
where employees->'employment'->'benefits' ? 'Insurance A'
OR employees->'employment'->'benefits' ? 'Insurance B';
I would like to use any instead like so:
select * from employees
where employees->'employment'->>'benefits' =
any('{Insurance A, Insurance B}'::text[]);
but this returns 0 results.. ideas?
What i've also tried
I tried the following syntaxes (all failed):
.. = any({'Insurance A','Insurance B'}::text[]);
.. = any('Insurance A'::text,'Insurance B'::text}::array);
.. = any({'Insurance A'::text,'Insurance B'::text}::array);
.. = any(['Insurance A'::text,'Insurance B'::text]::array);
employees->'employment'->'benefits' is a json array, so you should unnest it to use its elements in any comparison.
Use the function jsonb_array_elements_text() in lateral join:
select *
from
employees,
jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)
where
benefit = any('{Insurance A, Insurance B}'::text[]);
The syntax
from
employees,
jsonb_array_elements_text(employees->'employment'->'benefits')
is equivalent to
from
employees,
lateral jsonb_array_elements_text(employees->'employment'->'benefits')
The word lateral may be omitted. For the documentation:
LATERAL can also precede a function-call FROM item, but in this case
it is a noise word, because the function expression can refer to
earlier FROM items in any case.
See also: What is the difference between LATERAL and a subquery in PostgreSQL?
The syntax
from jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)
is a form of aliasing, per the documentation
Another form of table aliasing gives temporary names to the columns of
the table, as well as the table itself:
FROM table_reference [AS] alias ( column1 [, column2 [, ...]] )
You can use the containment operator ?| to check if the array contains any of the values you want.
select * from employees
where employees->'employment'->'benefits' ?| array['Insurance A', 'Insurance B']
If you happen to a case where you want all of the values to be in the array, then there's the ?& operator to check for that.

How to generate a predicate array of OR statements

I am trying to use the Criteria API instead of constructing queries as JPQL Strings as the Criteria API seems much better suited for this. However, I am having a few problems understanding how to construct the two following statements.
SELECT e
FROM Subject e
WHERE e.company = :c1
OR e.company = :c2
OR e.company = :c3
In this case I need to iterate over an unknown number of values (c1, c2, c3 etc.) to match to the same attribute.
SELECT e
FROM Subject e
WHERE e.company
LIKE :c1
OR e.account
LIKE :c1
OR e.email
LIKE :c1
In this case I need to pass in a single value (c1) and have a 'LIKE' comparison done on a specific range of attributes.
My current pattern looks something like this:
// Criteria
CriteriaBuilder builder = subjectDAO.criteriaBuilder();
CriteriaQuery<Subject> query = builder.createQuery(Subject.class);
// Root
Root<Subject> subject = query.from(Subject.class);
List<Predicate> predicates = new ArrayList();
for (String property : map.keySet()) {
String value = (String) coreFilter.get(map);
predicates.add(????? This is where I come unstuck ?????);
}
// pass all the predicates into the query
query.where(predicates.toArray(new Predicate[predicates.size()]));
NB. I don't have any problems constructing the Query object or specifying the Root or Joins. I am just having problems with the specificity of the above queries. For the sake of clarity just assume that all the attributes are String and don't require any joins.
The expression CriteriaQuery<T> where(Predicate... restrictions), as you can see in the javadoc,
Modify the query to restrict the query result according to the conjunction of the specified restriction predicates.
So, it makes the conjunction of the predicates in the list, i.e. it concatenates them with AND expressions. In order to concatenate them with OR expression, simply use CriteriaBuilder#or(Predicate... restrictions)
query.where(builder.or(predicates.toArray(new Predicate[] {})));

Sub Query in select clause with Squeryl

I'm trying to replicate the following query usine Squeryl.
SELECT c.order_number,p.customer,p.base,(
SELECT sum(quantity) FROM "Stock" s where s.base = p.base
) as stock
FROM "Card" c, "Part" p WHERE c."partId" = p."idField";
I have the following code for selecting the Cards and Parts but I cannot see a way to add a sumation into the select clause.
from(cards, parts)((c,p) =>
where(c.partId === p.id)
select(c,p)
Any help is much appreciated!
In Squeryl, you can use any Queryable object in the from clause of your query. So, to create a subquery, something like the following should work for you:
def subQuery = from(stock)(s => groupBy(s.base) compute(sum(s.quantity)))
from(cards, parts, subquery)((c, p, sq) =>
where(c.partId === p.idField and sq.key === p.base)
select(c.orderNumber, p.customer, sq.measures))
Of course the field names may vary slightly, just guessing at the class definitions. If you want the whole object for cards and parts instead of the single fields from the original query - just change the select clause to: select(c, p, sq.measures)