I am basically converting this query snippet:
I have a table A, and a table B (fk a.id), with a relationship where A can have many Bs.
I want to find A that is present in table B, which has values between X and Y.
Basically this query:
SELECT * FROM TABELA A AS a WHERE a.id IN (SELECT b.a_id FROM TABELA B AS B WHERE b.number_residents >= 100 AND b.number_residents <= 500)
Converting to criteria builder, I have this:
Subquery<HisCarAauuEntity> sub = cq.subquery(HisCarAauuEntity.class);
Root<HisCarAauuEntity> subRoot = sub.from(HisCarAauuEntity.class);
predicados.add(cb.in(aauu.get("id")).value(sub.select(subRoot.get("aId")).where(cb.and((cb.greaterThanOrEqualTo(subRoot.get("nResidents"), filtro.getNcargendesde()))), cb.lessThanOrEqualTo(subRoot.get("nResidents"), filtro.getNcargenhasta()))));
This works partially, because it returns me the result A that has the filter criteria, but if A has other rows in table B (that don't match the filter) it returns me that result too...
How do I make object A return the list of object B that contains ONLY the row that matches the filter sent?
As answered in Esper sum of snapshots (as opposed to sum of deltas), #unique(field) ensures that the sum is using specified field when summing up the values. That worked great except in the case listed below.
Given the following epl:
create schema StockTick(security string, price double);
create schema OrderEvent (orderId int, trader string, symbol string, strategy string,
quantity double);
select orderId, trader, symbol, strategy, sum(quantity)
from OrderEvent#unique(orderId) as o
full outer join StockTick#lastevent as t
on o.symbol = t.security
group by trader, symbol, strategy
The following events:
StockTick={security='IBM', price=99}
OrderEvent={orderID=1, trader="A", symbol='IBM', strategy="VWAP", quantity=10}
StockTick={security='IBM', price=99}
correctly provides the sum as sum(quantity)=10.0.
But if the StockTick did not happen first:
OrderEvent={orderID=1, trader="A", symbol='IBM', strategy="VWAP", quantity=10}
StockTick={security='IBM', price=99}
I still expected the value of quantity to be 10. But in this case it is sum(quantity)=20.0!!
Based on that #unique(field) does, I figure this shouldn’t be 20. Why is #unique(field) not being adhered to and what is needed in the query for the output to be unique on orderId for both cases?
The following set of events is also available to run on Esper Notebook
https://notebook.esperonline.net/#/notebook/2HE9662E6
In a streaming join the aggregation result aggregates all rows produced by the join. Since the join produces 2 rows as output with quantity 10 each the result is 20.
You can take an aggregation of the result of the join and unique by order id, you can use insert into. Like so:
insert into JoinedStream select orderId, trader, symbol, strategy, quantity
from OrderEvent#unique(orderId) as o
full outer join StockTick#lastevent as t
on o.symbol = t.security;
select orderId, trader, symbol, strategy, sum(quantity)
from JoinedStream#unique(orderId)
group by trader, symbol, strategy;
I have the following tables
ORDER (idOrder int, idCustomer int) [PK: idOrder]
ORDERLINE (idOrder int, idProduct int) [PK: idOrder, idProduct]
PRODUCT (idProduct int, rating hstore) [PK: idProduct]
In the PRODUCT table, 'rating' is a key/value column where the key is an idCustomer, and the value is an integer rating.
The query to count the orders containing a product on which the customer has given a good rating looks like this:
select count(distinct o.idOrder)
from order o, orderline l, product p
where o.idorder = l.idorder and l.idproduct = p.idproduct
and (p.rating->(o.idcust::varchar)::int) > 4;
The query plan seems correct, but this query takes forever. So I tried a different query, where I explode all the records in the hstore:
select count(distinct o.idOrder)
from order o, orderline l,
(select idproduct, skeys(p.rating) idcustomer, svals(p.rating) intrating from product) as p
where o.idorder = l.idorder and l.idproduct = p.idproduct
and o.idcustomer = p.idcustomer and p.intrating > 4;
This query takes only a few seconds. How is this possible? I assumed that exploding all values of an hstore would be quite inefficient, but it seems to be the opposite. Is it possible that I am not writing the first query correctly?
I'm suspecting it is because in the first query you are doing:
p.rating->(o.idcust::varchar)::int
a row at a time as the query iterates over the rest of the operations, whereas in the second query the hstore values are expanded in a single query. If you want more insight use EXPLAIN ANALYZE:
https://www.postgresql.org/docs/12/sql-explain.html
I have a collection in Azure CosmosDB where each document has 2 fields, say
{"a":1,"b":2}
{"a":1,"b":3}
{"a":2,"b":5}
and I want to return a set of possible values of B for each A, like this:
[{"a":1, "b":[2,3] },
{"a":2, "b":[5] }]
Trying SELECT c.a, ARRAY(SELECT DISTINCT c.b FROM c) FROM c GROUP BY c.a
I receive the error
Property reference 'c.b' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Same for ARRAY(select value c.b from c); and ARRAY_CONCAT does not look like an aggregate function.
Are there ways to do it without aggregating client-side?
Per my knowledge, this is not supported in Cosmos Db so far. Because Array is not aggregate function anyway which means it can't used with group by.
So, i suppose that you need to retrieve the data sort by a. Then loop the result to produce the b array mapping to the duplicate a.
For, Distinct values of b (output is in string format and values of b are comma separated)
SELECT a, String.Join(",", ARRAY_AGG(DISTINCT b)) AS list FROM c;
You can also use below, but the output format is not readable
SELECT a, ARRAY_AGG(DISTINCT b) AS list FROM c;
I have a 2 tables FIRST
id,rl_no,adm_date,fees
1,123456,14-11-10,100
2,987654,10-11-12,30
3,4343,14-11-17,20
and SECOND
id,rollno,fare,type
1,123456,20,bs
5,634452,1000,bs
3,123456,900,bs
4,123456,700,bs
My requirement is twofold,
1, i first need to get all columns from both tables with common rl_no. So i used:
SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno
The output is like this:
id,rl_no,adm_date,fees,rollno,fare,type
1,123456,14-11-10,100,123456,20,bs
1,123456,10-11-12,100,123456,900,bs
1,123456,14-11-17,100,123456,700,bs
2,Next i wanted to get the sum(fare) of those rollno that were common between the 2 tables and also whose fare >= fees from FIRST table group by rollno and id.
My query is:
SELECT x.ID,x.rl_no,,x.adm_date,x.fees,x.rollno,x.type,sum(x.fare) as "fare" from (SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno) x, FIRST y
WHERE x.rollno = y.rl_no AND x.fare >= y.fees AND x.type IS NOT NULL GROUP BY x.rollno,x.ID ;
But this is throwing in exceptions.
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
The expected output will be like this:
id,rollno,adm_date,fare,type
1,123456,14-11-10,1620,bs
So could someone care to show an oracle newbie what i'm doing wrong here?
It looks like there's a couple different problems here;
Firstly, you're trying to group by an x.ID column which doesn't exist; it looks like you'll want to add ID to the selected columns in your sub-query.
Secondly, when aggregating with GROUP BY, all selected columns need to be either listed in the GROUP BY statement or aggregated. If you're grouping by rollno and ID, what do you want to have happen to all the extra values for adm_date, fees, and type? Are those always going to be the same for each distinct rollno and ID pair?
If so, simply add them to the GROUP BY statement, ie,
GROUP BY adm_date, fees, type, rollno, ID
If not, you'll need to work out exactly how you want to select which one to be output; If you've got output like your example (adding in an ID column here)
ID,adm_date,fees,rollno,fare,type
1,14-11-10,100,123456,20,bs
1,10-11-12,100,123456,900,bs
1,14-11-17,100,123456,700,bs
Call that result set 'a'. If I run;
SELECT a.ID, a.rollno, SUM(a.fare) as total_fare
FROM a
GROUP BY a.ID, a.rollno
Then the result will be a single row;
ID,rollno,total_fare
1,123456,1620
So, if you also select the adm_date, fees, and type columns, oracle has no idea what you mean to do with them. You're not using them for grouping, and you're not telling oracle how you want to pick which one to use.
You could do something like
SELECT a.ID,
FIRST(a.adm_date) as first_adm_date,
FIRST(a.fees) as first_fees,
a.rollno,
SUM(a.fare) as total_fare,
FIRST(a.type) as first_type
FROM a
GROUP BY a.ID, a.rollno
Which would give the result;
ID,first_adm_date,first_fees,rollno,total_fare,first_type
1,14-11-10,100,123456,1620,bs
I'm not sure if that's what you mean to do though.