Postgresql array_agg of multiple columns with JDBC - postgresql

I'm trying to join a table that might have multiple entries for the given id and aggregate the rows corresponding to this id in an array. This looks as follows in the SQL query:
SELECT * from data
LEFT JOIN (select id, array_agg(row(foo, bar)) AS foo_bar_data from foo_bar_table group by id) AS temp using(id)
This works as intended, but I'm having trouble reading out the result in JDBC.
ResultSet rs = st.executeQuery(...)
Array a = rs.getArray("foo_bar_data")
// Now I want to iterate over the array, reading the values foo and bar of each item.
My efforts so far always ended in a Method org.postgresql.jdbc4.Jdbc4Array.getArrayImpl(long,int,Map) is not yet implemented. exception. How can I iterate over a, retrieving the values foo and bar?
Edit: I should possibly also mention, that foo and bar don't have the same type.

Postgres JDBC driver does not support anything except basic types (numbers, date/timestamp, string) as JDBC array. You can call array_agg twice and get two arrays on each row:
try (Connection db = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres");
ResultSet rs = db.createStatement().executeQuery("select array_agg(i), array_agg(s) from (select 1 i, 'a' s union select 2 i, 'b' s) t")) {
rs.next();
System.out.println(Arrays.toString((Object[]) rs.getArray(1).getArray()));
System.out.println(Arrays.toString((Object[]) rs.getArray(2).getArray()));
}

Related

how to call spring jap query none parameters

I use spring data jpa with native query
I have already some query like this
How to use native query none parameter.
String q="SELECT t1.blockNumber-1 FROM someTAble t1 LEFT JOIN someTAble t2 ON t2.blockNumber = t1.blockNumber-1 WHERE t2.blockNumber IS NULL AND t1.blockNumber> 0 ORDER BY t1.blockNumber";
#Query(value = q,nativeQuery = true)
List<Entity> findByBlockNumberIs();
they are occur errors Column 'sequence' not found.
That query means are when i insert some Contiguous data int value then i find missing data.
But
this query working
SELECT *,t1.blockNumber-1 FROM someTAble t1 LEFT JOIN someTAble t2 ON t2.blockNumber = t1.blockNumber-1 WHERE t2.blockNumber IS NULL AND t1.blockNumber> 0 ORDER BY t1.blockNumber
The difference between the two queries is whether there is a '*' or not
how to change simple to my query.
How to i changed error
OR How to use spring data jpa predicate
QEntity qBe1= QEntity .blockEntity;
QEntity qBe2= QEntity .blockEntity;
build.and(qBe2.blockNumber.eq(be.getBlockNumber()-1))
.and(qBe2.blockNumber.isNull().and(qBe1.blockNumber.gt(0)));
is predicate can use left join?
well...
use this.
List<Integer> findByBlockNumber()

Get results from HQL query with the same order as given list

I'm trying make a query with HQL that will stay with the same order as given list of IDs. I know it's possible with SQL but I can't find any way to do it with HQL (and I cannot do it with native SQL because I got many joins)
Example
fingerIds = [3,1,10,4]
SELECT p FROM People p
JOIN FETCH p.fingers f
WHERE f.id IN :fingerIds
DB: PostgreSQL 10.4
Hibernate: 4.3.11.Final
Eg. Given list of IDs: [3,1,10,4]
Actual result's order: [1,3,4,10]
Expected result's order: [3,1,10,4]
You can obtain the order by adding to your query the keyword FIELD, in your example:
SELECT p FROM People p
JOIN FETCH p.fingers f
WHERE f.id IN :fingerIds
ORDER BY FIELD(f.ID,3,1,10,4)
Ofc you can replace the numbers with your variable :fingerIds
You can find more about that command here.
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.

PostGres joins Using JSONB

I have two tables which look like such
Organizations
Id (primary_key. big int)
Name (text)
CustomInformations
Id (primary_key. big int)
ConnectedIdentifiers (JSONB)
Info (text)
CustomInformations's ConnectedIdentifiers column contains a JSONB structure which looks like
{ 'organizations': [1,2,3] }
This means that there's an array of organizations with those ids 1, 2, 3, which are related to that particular CustomInformation
I'm trying to do a JOIN where given a CustomInformation Id will also get me all the Organizations names
I tried this after looking at some examples:
SELECT * FROM CustomInformations ci
INNER JOIN Organizations o on jsonb_array_elements(ci.ConnectedIdentifiers->'19') = o.id
WHERE
ci.id = 5
I got an error No operator matches the given name and argument type(s). You might need to add explicit type casts.
Is this the right approach? And if so what is wrong with my syntax?
Thanks
You cannot use jsonb_array_elements() in this way because the function returns set of rows. It should be placed in a lateral join instead. Use jsonb_array_elements_text() to get array elements as text and cast these elements to bigint:
select ci.*, o.*
from custominfo ci
-- lateral join
cross join jsonb_array_elements_text(ci.connectedidentifiers->'organizations') ar(elem)
join organizations o
on elem::bigint = o.id
where ci.id = 5

Embedded Select for From value

Having difficulty framing my question for Google.
I am trying to embed a select statement which pulls partition table names from a view. I want to cycle through these tables and do a search within them for a value count.
I have:
SELECT COUNT(objectA)
FROM (SELECT partitiontablename
FROM partitions
WHERE tablename = 'x')
AS tableNameQuery
WHERE objectB = 1
I am getting ERROR: column "objectB" does not exist
The partitions tables do have objectB (they are the same table structure). Can you guide me to what i am doing wrong?
Thank you!
Try this query:
SELECT COUNT(objectA)
FROM (
SELECT partitiontablename, objectB, objectA
FROM partitions
WHERE tablename = 'x'
) AS tableNameQuery
WHERE objectB = 1
The subquery in your query retrieves only partitiontablename column, so the outer query sees only that column, but doesn't see objectB.
The same problem is with objectA used in COUNT() in the outer query.

How to ORDER BY non-column field?

I am trying to create an Entity SQL that is a union of two sub-queries.
(SELECT VALUE DISTINCT ROW(e.ColumnA, e.ColumnB, 1 AS Rank) FROM Context.Entity AS E WHERE ...)
UNION ALL
(SELECT VALUE DISTINCT ROW(e.ColumnA, e.ColumnB, 2 AS Rank) FROM Context.Entity AS E WHERE ...)
ORDER BY *??* LIMIT 50
I have tried:
ORDER BY Rank
and
ORDER BY e.Rank
but I keep getting:
System.Data.EntitySqlException: The query syntax is not valid. Near keyword 'ORDER'
Edit:
This is Entity Framework. In C#, the query is executed using:
var esql = "...";
ObjectParameter parameter0 = new ObjectParameter("p0", value1);
ObjectParameter parameter1 = new ObjectParameter("p1", value2);
ObjectQuery<DbDataRecord> query = context.CreateQuery<DbDataRecord>(esql, parameter0, parameter1);
var queryResults = query.Execute(MergeOption.NoTracking);
There is only a small portion of my application where I have to resort to using Entity SQL. Generally, the main use case is when I need to do: "WHERE Column LIKE 'A % value % with % multiple % wildcards'".
I do not think it is a problem with the Rank column. I do think it is how I am trying to apply an order by to two different esql statements joined by union all. Could someone suggest:
How to apply a ORDER BY to this kind of UNION/UNION ALL statment
How to order by the non-entity column expression.
Thanks.