jpa postgres - query result difference with like on TEXT fields - sql

I'm trying to make a query to search items structured as follows:
IssueCategory --* Issue (one to many)
using the following JPQL
select count(z) from IssueCategory z join z.issues x
where
lower(cast(function('lo_get', cast(x.diagnosis as integer)) as text)) like lower(concat('TEXT TO SEARCH', '%'))
where diagnosis is a Issue's String field with #Lob annotation, mapped as a text field in postgres:
CREATE TABLE issues (
...
diagnosis text,
...
)
this query produces the following query
select count(issuecateg0_.id) as col_0_0_
from issue_categories issuecateg0_
inner join issues issues1_ on issuecateg0_.id=issues1_.category_id
where lower(cast(lo_get(cast(issues1_.diagnosis as int4)) as text)) like lower(('TEXT TO SEARCH'||'%'))
Obviously in origin the "TEXT TO SEARCH" was passed as a parameter to the query.
The problem is: when I execute the JPQL query, it returns 0, but if I execute the generated query directly in postgres, I get 1.
Does anyone know of behaviours like this one?

I finally changed to the following conditions:
lower(function('encode', (function('lo_get', cast(x.diagnosis as integer))), 'escape') like lower(concat('TEXT TO SEARCH', '%'))

Related

Nested search without keys in jsonb in PostgreSql

The question is about selection from JSON in PostgreSQL.
For example, application contains translation data in jsonb:
{
"en":{
"locale":"en",
"title":"Title",
"textShort":"Short text",
"textFull":"Full text"
}
"ru":{
"locale":"ru",
"title":"Заголовок",
"textShort":"Короткий текст",
"textFull":"Подробный текст"
}
}
This query works successfully:
select *
from content_records
where translations::json->'en'->>'title' like '%Title.';
But this query requires information about the locale, but the case is that we don't know anything about locales and search must be done for every locale, for example:
select *
from content_records
where translations::json->'any locale'->>'title' like '%Title.';
In MySQL it works as:
select *
from content_records
where LOWER(JSON_EXTRACT(translations, '$.*.title')) LIKE LOWER(:title);
There is the similar function in PostgreSQL:
json_extract_path, but it requires keywords and you can't miss the key as the symbol * does in MySQL.
The question is - how to do the selection of a nested JSON in this situation?
Unfortunately, in Postgres you have to "unnest" the keys first.
Something like this:
select t.*, cr.translations
from content_records cr
cross join lateral jsonb_object_keys(translations) as t(locale)
where lower(cr.translations -> t.locale ->> 'title') like '%title';
Note that if a title matches in more than one locale, you will get one row for each matching locale. If you don't want that, you can do the following:
select cr.*
from content_records cr
where exists (select *
from jsonb_object_keys(cr.translations) as t(locale)
where lower(cr.translations -> t.locale ->> 'title') like '%title')

multiplying modified colums to form new column

I want a query like:
select tp.package_rate, sum(sell) as sold_quantity , select(tp.package_rate * sold_quantity ) as sell_amount from tbl_ticket_package tp where tp.event_id=1001
here the system firing error while doing the multiplication as
sold_quantity is invalid column
another problem is that in multiplication I want to use package_rate which got by select query from tp.package_rate but it multiplying with all package_rate of the table but I want only specific package_rate which was output of select query
What would you suggest? I want to bind this query in gridview . is there any way to do it using ASP.net gridview?
Your problem is that you are referring to sold_quantity here :
select(tp.package_rate * sold_quantity )
The alias is not recognized at this point.You will have to replace it with sum(sales). You will also have to group by tp.package_rate.
Your query should ideally be like :
select tp.package_rate, sum(sell) as sold_quantity ,
(tp.package_rate * sum(sell) ) as sell_amount from tbl_ticket_package tp
where tp.event_id=1001 group by tp.package_rate;
I am guessing that tp.package_rate is unique for a given event_id, from latter part of your question. If that's not the case, the sql you have written makes no sense.

Hibernate return empty result if using LIKE condition with univarchar columns (Sybase)

Let's suppose I have a table: Person(Name: univarchar) and this table contains a row "abc".
I search Person by using Hibernate (Criteria API and HQL):
Criteria API:
Criteria c = session.createCriteria(Person.class);
c.add(Restrictions.ilike(name,"abc"));
return c.list();
HQL:
String query = "from Person where lower(name) like :name";
Query q = session.createQuery(query);
query.setString("name","abc");
return query.list();
It return empty result. However, when I use Interactive SQL of Sybase to execute SQL statement that is generated by Hibernate, it return a row "abc".
I found a solution for HQL case. This is to use rtrim function:
String query = "from Person where lower(rtrim(name)) like :name";
...
But my problem is I want to use Criteria API and I cannot find any ways to trim name column by using Criteria API.
Thanks and sorry for my poor English.
Have you tried with this code :
Criteria c = session.createCriteria(Person.class);
c.add(Restrictions.ilike(name,"abc",MatchMode.ANYWHERE));
return c.list();
If this will not work then Read this. Its similar Just he wants to trim while Order you want to trim while Restrictions.

Postgres SELECT * FROM Table where array has element

I am using Postgres 9.3.2 to make a database of contacts.
Example: If i have a row in my table that looks something like this.
{
firstName : "First name"
lastName : "Last name"
emails : ["email#one.com", "email#two.com", "email#three.com]
}
PS: firstName, lastName and emails are columns in my db and the value associated is the value for that column for that specific row.
I want to be able to query the db so that if i query for the email "email#four.com" the result is nothing but if i query for "email#two.com" the result will be the above row entry.
I dont think the query
"Select * from contactTable where emails="email#two.com""
will work. instead i want to do something like
"Select * from contactTable where emails contains "email#two.com""
any ideas on how to do this?
"Select * from contactTable where emails contains "email#two.com""
I think you want:
"Select * from contactTable where thejsonfield -> emails
Example setup, after fixing up your totally broken json:
CREATE TABLE contacts AS SELECT '{
"firstName" : "First name",
"lastName" : "Last name",
"emails" : ["email#one.com", "email#two.com", "email#three.com"]
}'::json AS myjsonfield;
The following will work in PostgreSQL 9.4, but unfortunately does not in 9.3 due to the oversight of the missing json_array_elements_text function:
select *
from contacts,
lateral json_array_elements_text(myjsonfield -> 'emails') email
where email = 'email#two.com';
For 9.3, you have to use a clumsier method to scan the json array for matching values:
select *
from contacts,
lateral json_array_length(myjsonfield -> 'emails') numemails,
lateral generate_series(0, numemails) n
WHERE json_array_element_text(myjsonfield -> 'emails', n) = 'email#two.com';
You can't use the simple IN or = ANY constructs because (at this point) PostgreSQL doesn't understand that you might have a json array, so it'll fail with:
regress=> SELECT * FROM contacts WHERE 'email#two.com' = ANY (myjsonfield->'emails');
ERROR: op ANY/ALL (array) requires array on right side
LINE 1: SELECT * FROM contacts WHERE 'email#two.com' = ANY (myjsonfi...
^
as it expects a PostgreSQL array, not a json array, and there's no convenient builtin to turn a json array into a PostgreSQL array yet.
Postgres has support for parsing JSON. Here is documentation: http://www.postgresql.org/docs/9.3/static/functions-json.html. I can't give you more detailed answer since you didn't provide exact data and schema, but it's easy to find the right function in documentation.

How to extract the repeatable part of lucene query?

I have 4 fields, docContent, visibility, docOwner and docType. I want to get all docType:ProfileDocument except those with visibility:1. But the owner of each document can say that his document with visibility:1 can be returned from the search result. The query bellow searches for asd, returning all documents that matches the term and their visibility is not 1 except for docOwner:390. The query works but the docType:ProfileDocument is repeated twice. How to refactor the query so docType:ProfileDocument be presented only once?
docContent:asd
AND(
(NOT visibility:1 AND docType:ProfileDocument)
OR ( docOwner:390 AND visibility:1 AND docType:ProfileDocument)
)
I tried this but I failed:
docContent:asd
AND(
(((NOT visibility:1)
OR ( docOwner:390 AND visibility:1))
AND docType:ProfileDocument)
)
The AND NOT operator cannot be used with just one term. For example, the following search will return no results:
AND NOT "jakarta apache"
Reference: http://drupal.org/node/375446