I have a table in a Postgres 9.3 database with a json column like this:
CREATE mytable (
mycolumn json
)
I would like to execute queries from a Java application that look like this:
SELECT
mycolumn->>'somefield',
count(*)
FROM
mytable
GROUP BY
mycolumn->>'somefield'
When I try to use a PreparedStatement like this:
SELECT
mycolumn->>?,
count(*)
FROM
mytable
GROUP BY
mycolumn->>?
I get the following error:
PSQLException: ERROR: column "mytable.mycolumn" must appear in the GROUP BY clause or be used in an aggregate function
It makes sense that this happens because Postgres cannot guarantee that the two positional parameters are the same.
Using psql, I can prepare a statement like this:
PREPARE mystatement AS
SELECT
mycolumn->>$1,
count(*)
FROM
mytable
GROUP BY
mycolumn->>$1
Is it possible to do this with JDBC?
No, this isn't possible. JDBC only has positional parameters, and therefor the PostgreSQL driver will render it as:
PREPARE mystatement AS
SELECT
mycolumn->>$1,
count(*)
FROM
mytable
GROUP BY
mycolumn->>$2
And as the value of $1 is not necessarily the same as $2, the parser of PostgreSQL will reject it as you are potentially not grouping on the same column.
The solution might be to do:
SELECT a.aColumnLabel, count(*)
FROM (
SELECT mycolumn->>? as aColumnLabel
FROM mytable
) a
GROUP BY a.aColumnLabel
Related
ّ am trying to insert multiple records got from the join table to another table user_to_property. In the user_to_property table user_to_property_id is primary, not null it is not autoincrementing. So I am trying to add user_to_property_id manually by an increment of 1.
WITH selectedData AS
( -- selection of the data that needs to be inserted
SELECT t2.user_id as userId
FROM property_lines t1
INNER JOIN user t2 ON t1.account_id = t2.account_id
)
INSERT INTO user_to_property (user_to_property_id, user_id, property_id, created_date)
VALUES ((SELECT MAX( user_to_property_id )+1 FROM user_to_property),(SELECT
selectedData.userId
FROM selectedData),3,now());
The above query gives me the below error:
ERROR: more than one row returned by a subquery used as an expression
How to insert multiple records to a table from the join of other tables? where the user_to_property table contains a unique record for the same user-id and property_id there should be only 1 record.
Typically for Insert you use either values or select. The structure values( select...) often (generally?) just causes more trouble than it worth, and it is never necessary. You can always select a constant or an expression. In this case convert to just select. For generating your ID get the max value from your table and then just add the row_number that you are inserting: (see demo)
insert into user_to_property(user_to_property_id
, user_id
, property_id
, created
)
with start_with(current_max_id) as
( select max(user_to_property_id) from user_to_property )
select current_max_id + id_incr, user_id, 3, now()
from (
select t2.user_id, row_number() over() id_incr
from property_lines t1
join users t2 on t1.account_id = t2.account_id
) js
join start_with on true;
A couple notes:
DO NOT use user for table name, or any other object name. It is a
documented reserved word by both Postgres and SQL standard (and has
been since Postgres v7.1 and the SQL 92 Standard at lest).
You really should create another column or change the column type
user_to_property_id to auto-generated. Using Max()+1, or
anything based on that idea, is a virtual guarantee you will generate
duplicate keys. Much to the amusement of users and developers alike.
What happens in an MVCC when 2 users run the query concurrently.
I'm working with PostgresQL database with a python script. I have a query like this:
UPDATE orders SET id=%s, client=%s, contents=%s, adress=%s, detail=%s, price=%s HAVING MIN(id)
It works fine, but PyCharm says that "having" statement doesn't exist and i should use "where" (while "where" gives an exception in this query because I'm using "MIN"). And I have SQL dialect in PyCharm set to "PostgresQL". Any ways to fix this annoying issue?
UPD: my bad, this query isn't working. It somehow didn't throw an exception in python, but the row in database wasn't updated. Then what query should I use to update row with the least id?
You can get min(id) in the same query with either a sub-query or a CTE. Perhaps something like:
update some_tbl
set col = 1
where id = (select min(id)
from some_tbl
) ;
OR
with lowers(mid) as
(select min(id)
from some_tbl
)
update some_tbl st
set col = 1
from lowers l
where st.id = l.mid;
I am trying to add component 'tNetezzainput' in Talend
with query like
select col1,col2 from
(select col1,col2 from tab2 )
when i run sub query independently it is allowing to get schema
but when i run above query it is showing error like
org.netezza.error.NzSQLexception:ERROR
(above query)
You need to add an alias after the parentheses (I randomly chose ‘x’):
select col1,col2 from
(select col1,col2 from tab2 ) x
SELECT pl_id,
distinct ON (store.store_ID),
in_user_id
FROM plan1.plan_copy_levl copy1
INNER JOIN plan1._PLAN_STORE store
ON copy1.PLAN_ID = store .PLAN_ID;
while running this query in postgres server i am getting the below error..How to use the distinct clause..in above code plan 1 is the schema name.
ERROR: syntax error at or near "distinct" LINE 2: distinct ON
(store.store_ID),
You are missing an order by where the first set of rows should be the ones specified in the distinct on clause. Also, the distinct on clause should be at start of the selection list.
Try this:
SELECT distinct ON (store_ID) store.store_ID, pl_id,
in_user_id
FROM plan1.plan_copy_levl copy1
INNER JOIN plan1._PLAN_STORE store
ON copy1.PLAN_ID = store .PLAN_ID
order by store_ID, pl_id;
When I execute this query in SQL Server which calls to IBM,
Select * from openquery(ibm,'
Select COST_AMT,'Query1' as Query
from table
where clause
with ur;
')
union
Select * from openquery(ibm,'
Select COST_AMT,'Query2' as Query
from table
different where clause
with ur;
')
I get different results in the union query than when I execute them separately and bring the results in together. I have tried the union query inside the openquery so I believe this is an IBM thing. The results appear to be a distinct selection of COST_AMT sorted by lowest to highest.
ie:
1,Query1
2,Query1
3,Query1
1,Query2
2,Query2
3,Query2
but the data is actually like this:
1,Query1
1,Query1
1,Query1
2,Query1
2,Query1
3,Query1
1,Query2
1,Query2
1,Query2
2,Query2
2,Query2
3,Query1
Am I missing something about the ibm union query? I realize I could sum and get the answer, (which is what I plan no doing) but I want to know more about why this is happening.
This has nothing to do with "ibm" or "db2" -- the SQL UNION operator removes duplicates. To retain duplicates use UNION ALL.