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.
Related
Question
How can I achieve aggregation of the boolean array in the LEFT JOIN LATERAL?
A result can have many owners.
There can only by one ownership record that is original - that's because we are supporting the assignment of a result by the original owner to a new owner.
In this case, we would have two ownership records, differing in the owner_id as well as the original boolean value of the row.
ERD
Note: There is a small error in this ERD. The owners table has id INT and owner UUID (not just a single id column). This probably doesn't contribute to the issue - but it does make the SQL a little more gnarly than it should be.
Results
guid
assigned
061c840a-f8d2-4200-8d17-40b35650de40
{true}
074e3e67-c22a-4681-a5da-844b943a0cf9
"{false,true}"
084de451-6531-4997-b788-17819f29a6cb
{true}
Desired Results
guid
assigned
061c840a-f8d2-4200-8d17-40b35650de40
true
074e3e67-c22a-4681-a5da-844b943a0cf9
false
084de451-6531-4997-b788-17819f29a6cb
true
SQL
SELECT DISTINCT ON (results.id) results.id as guid,
assigned
FROM results
LEFT JOIN LATERAL ( SELECT *,
(SELECT array(SELECT ownership.original
FROM ownership
where ownership.result_id = results.id)) as assigned
FROM (ownership
LEFT JOIN owners on (ownership.owner_id = owners.id))) as resultOwnership
ON results.id = resultOwnership.result_id
WHERE resultOwnership.owner = '2a09be27-3fed-4c48-9c63-6877dddc95f5';
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()));
}
I have the next query which does not work:
UPDATE item
SET popularity= (CASE
WHEN (select SUM(io.quantity) from item i NATURAL JOIN itemorder io GROUP BY io.item_id) > 3 THEN TRUE
ELSE FALSE
END);
Here I want to compare each line of inner SELECT SUM value with 3 and update popularity. But SQL gives error:
ERROR: more than one row returned by a subquery used as an expression
I understand that inner SELECT returns many values, but can smb help me in how to compare each line. In other words make loop.
When using a subquery you need to get a single row back, so you're effectively doing a query for each record in the item table.
UPDATE item i
SET popularity = (SELECT SUM(io.quantity) FROM itemorder io
WHERE io.item_id = i.item_id) > 3;
An alternative (which is a postgresql extension) is to use a derived table in a FROM clause.
UPDATE item i2
SET popularity = x.orders > 3
FROM (select i.item_id, SUM(io.quantity) as orders
from item i NATURAL JOIN itemorder io GROUP BY io.item_id)
as x(item_id,orders)
WHERE i2.item_id = x.item_id
Here you're doing a single group clause as you had, and we're joining the table to be updated with the results of the group.
I know this is an often asked question, but I've tried to resolve this myself and could not.
I've got 2 tables to join and now it's returning a duplicate value from the right table.
select am.Journal
,am.EntryNumber
,am.PayInvoice
,am.PayDiscAllowed
,am.PayTaxAmtDisc
,am.PayGrossPayment
,tm.*
from CshJnlPay am right join
(select
Invoice
,SUM(NetSalesValue) as NetSalesValue
,SUM(DiscValue) as DiscValue
,SUM(TaxValue) as TaxValue
,SUM(QtyInvoiced) as QtyInvoiced
from Salesdetail
group by Invoice) tm
on am.PayInvoice = tm.Invoice
where Invoice = 'C90831'
If the query returns 2 rows with the same data from the right table then you have 2 rows in the left table with the same invoice number...
You should check the left table with this query
Select * from CshJnlPay where PayInvoice = 'C90831'
You should get two rows.
In my application i have a query that do multiple joins with a table position. Just like this:
SELECT *
FROM (...) as trips
join trip as t on trips.trip_id = t.trip_id
left outer join vehicle as v on v.vehicle_id = t.trip_vehicle_id
left outer join position as start on trips.start_position_id = start.position_id and start.position_vehicle_id = v.vehicle_id
left outer join position as "end" on trips.end_position_id = "end".position_id and "end".position_vehicle_id = v.vehicle_id
left outer join position as last on trips.last_position_id = last.position_id and last.position_vehicle_id = v.vehicle_id;
My table position has 35 columns(for example position_id).
When I run the query, in result should appear the table position 3 times, start, end and last. But postgres can not distinguish between, for exemplar, start.position_id, end.position_id and last.position_id. So this 3 columns are group and appear as one, position_id.
As the data from start.position_id and end.position_id are different, the column, position_id, that appear in result, it's empty.
Without having to rename all the columns, like this: start.position_id as start_position_id.
How can i get each group of data separately, for exemple, get all columns from the table 'start'. In MYSQL i can do this operation by calling fetch_fields, and give the function an alias, like 'start'.
But i can i do this in Postgres?
Best Regards,
Nuno Oliveira
My understanding is that you can't (or find it difficult to) discern between which table each column with a shared name (such as "position_id") belongs to, but only need to see one of the sets of shared columns at any one time. If that is the case, use tablename.* in your SELECT, so SELECT trips.*, start.*... would show the columns from trips and start, but no columns from other tables involved in the join.
SELECT [...,] start.* [,...] FROM [...] atable AS start [...]