show query parameters that don't select anything - sql

I have a table with a text column and I would like to select all rows that match the list of search parameters that were provided by the user:
select * from value where value.text in ('Mary', 'Steve', 'Walter');
In addition, I want to notify the user if any of his search terms could not be found. Let's say 'Steve' does not exist in the value.text column, how can I write a query that will show 'Steve'? As that information does not exist in any table, I have no idea how it could be done using a SQL query.
The actual Hibernate code looks like this:
List<String> searchItemList = new ArrayList<>();
searchItemList.add("Mary");
searchItemList.add("Steve");
searchItemList.add("Walter");
Query query = em.createQuery("select v from Value as v where v.text in ( :searchitemlist )");
query.setParameter("searchitemlist", searchItemList);
List result = query.getResultList();
log.info("{}", result.size());
log.info("{}", result);
The searchItemList is a list of all search terms provided by the user. Can be a few hundreds lines long. The current workaround is to search the value table once for each searchItem and note all queries that return 0 rows. That is rather inefficient, surely there is a better approach? Please advise.

You can use the following query to get an array of search items that exist in the database
SELECT DISTINCT value.text from value where value.text in ('Mary', 'Steve', 'Walter');
after running this query, If we assume that the answer is stored in an array called result, notExistSearchListItems will give you the final result
IEnumerable<string> notExistSearchListItems = searchItemList.Except(result);

Related

Is possible do Select * form DynamicValue to perform a query like this in Navision?

Is possible do Select * form DynamicValue to perform a query like this in Navision?
Thanks in advance
To perform a sql query li this select * from DynamicValue You must do something like this.
Imagine that you have a table and you are going to show the data in a page or form.
Variables:
RecDynamicValue (Table).
PagDynamicValues (Page).
Code:
RecDynamicValue.RESET; //Clean filters
CLEAR(PagDynamicValues);
PagDynamicValues.SETTABLEVIEW(RecDynamicValue); //Set RecDynamicValue (Table)
PagDynamicValues.RUN; (Open Page)
In this code when page is open you can see al records from DynamicValue table like a Select * from DynamicValue.
If you need perform a loop for all records from DynamicValue table in code try this:
RecDynamicValue.RESET;
IF RecDynamicValue.FINDSET THEN REPEAT //Repeat clausule for a loop
//Loop...
//Loop...
//Loop...
UNTIL RecDynamicValue.NEXT = 0; //Repeat until last value
In all cases first you need declare a variable, SubType = Record and specified ID or name of record.
You can not change the value of the table variable by code.
But perhaps you can use RecordRef function to do that.
For example:
RecRef.OPEN(27); //Id of ItemTable
RecRef.FINDFIRST;
FldRef := RecRef.FIELD(3); // Item.Description;
FldRef.VALUE('New description');
RecRef.MODIFY;
In your case your DynamicValue is parameter to RecRef.OPEN("Your Dynamic Value") here you need specified value ID of your table.
You can also perform a loop using RecorRef.

Can I combine these two JOOQ queries into one?

I have two queries which look at separate database tables and find items from a JSONB column in each table that are in the format ["tag1","tag2","tag3"] etc. The purpose of the queries are to populate a list for a predictive dropdown i.e. if the list contains "dog" and the user types "d", "dog" should be returned. Each of these queries works individually and I can easily combine them into a single JOOQ query?
final Field<String> value = field(name("A", "value"), String.class);
final Result<Record1<String>> res1 = sql.dsl()
.selectDistinct(value)
.from(CAMPAIGN,lateral(table("jsonb_array_elements_text({0})", CAMPAIGN.TAGS)).as("A"))
.where(CAMPAIGN.STORE_KEY.equal(campaign.getStoreKey()))
.and(CAMPAIGN.CAMPAIGN_KEY.notEqual(campaignKey))
.and(value.like(search + "%%"))
.fetch();
final Result<Record1<String>> res2 = sql.dsl()
.selectDistinct(value)
.from(STOREFRONT, lateral(table("jsonb_array_elements_text({0})", STOREFRONT.TAGS)).as("A"))
.where(STOREFRONT.STORE_KEY.equal(campaign.getStoreKey()))
.and(value.like(search + "%%")).fetch();
Sure! In SQL, "combining" two queries is mostly implemented using UNION [ ALL ] (where ALL indicates that you want to maintain duplicates). In your case, write the following:
final Result<Record1<String>> result =
sql.dsl()
.select(value)
.from(
CAMPAIGN,
lateral(table("jsonb_array_elements_text({0})", CAMPAIGN.TAGS)).as("A"))
.where(CAMPAIGN.STORE_KEY.equal(campaign.getStoreKey()))
.and(CAMPAIGN.CAMPAIGN_KEY.notEqual(campaignKey))
.and(value.like(search + "%%"))
.union(
select(value)
.from(
STOREFRONT,
lateral(table("jsonb_array_elements_text({0})", STOREFRONT.TAGS)).as("A"))
.where(STOREFRONT.STORE_KEY.equal(campaign.getStoreKey()))
.and(value.like(search + "%%")))
.fetch();
Note that I have replaced selectDistinct() by select(), because the UNION operation already removes duplicates, so there's no need to remove duplicates in each individual union subquery.

Get all entries for a specific json tag only in postgresql

I have a database with a json field which has multiple parts including one called tags, there are other entries as below but I want to return only the fields with "{"tags":{"+good":true}}".
"{"tags":{"+good":true}}"
"{"has_temps":false,"tags":{"+good":true}}"
"{"tags":{"+good":true}}"
"{"has_temps":false,"too_long":true,"too_long_as_of":"2016-02-12T12:28:28.238+00:00","tags":{"+good":true}}"
I can get part of the way there with this statement in my where clause trips.metadata->'tags'->>'+good' = 'true' but that returns all instances where tags are good and true including all entries above. I want to return entries with the specific statement "{"tags":{"+good":true}}" only. So taking out the two entries that begin has_temps.
Any thoughts on how to do this?
With jsonb column the solution is obvious:
with trips(metadata) as (
values
('{"tags":{"+good":true}}'::jsonb),
('{"has_temps":false,"tags":{"+good":true}}'),
('{"tags":{"+good":true}}'),
('{"has_temps":false,"too_long":true,"too_long_as_of":"2016-02-12T12:28:28.238+00:00","tags":{"+good":true}}')
)
select *
from trips
where metadata = '{"tags":{"+good":true}}';
metadata
-------------------------
{"tags":{"+good":true}}
{"tags":{"+good":true}}
(2 rows)
If the column's type is json then you should cast it to jsonb:
...
where metadata::jsonb = '{"tags":{"+good":true}}';
If I get you right, you can check text value of the "tags" key, like here:
select true
where '{"has_temps":false,"too_long":true,"too_long_as_of":"2016-02-12T12:28:28.238+00:00","tags":{"+good":true}}'::json->>'tags'
= '{"+good":true}'

Using linQ to perform a simple select where

I am using VS2013 with SQL server 2012, VB.net. I am developing a web application.
Let me say before I ask the question that this will probably be extremely simple for this board but I have not been able to find this through googling.
I have an SQL table that holds some data, two columns (settingName (nvarchar) and settingValue (float)). I want to do the following but using LinQ.
SELECT Settingvalue
FROM Settings
WHERE settingName = 'Name1'
I have the following so far in VB.
Dim db As New GMConnectionDataContext
Dim result = From a In db.Settings
Where a.SettingName = "Name1"
Select a.SettingValue
txtEgdon.Text = result
This doesn't work as result is a double but if I add .tostring to result then the output in the text box is the full linq query not the result I am looing for.
I just need to understand this simple query so I can build on it but I just cant get it and any help offered would be great.
This is because your result is an IQueryable and not a single value(even if you expect it to be). This is also why ToString will get you the SQL that will be run against your DB.
You need to get either the First or if you are really sure this would be a single value get Single. The OrDefaults are used in the case that no value is returned so the result will be null.
A Few options:
// You expect 1 to many results and get the first
txtEgdon.Text = result.First().ToString()
// You expect 0 to many results and get the first or null in case of zero results
txtEgdon.Text = result.FirstOrDefault().ToString()
// You expect exactly 1 result and get it (you will get an exception if no results are returned)
txtEgdon.Text = result.Single().ToString()
// You expect exactly 0 or 1 results and get null or the result
txtEgdon.Text = result.SingleOrDefault().ToString()
I would prefer the FirstOrDefault()

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.