How to use where in list items - sql

I have a database as below:
TABLE_B:
ID Name LISTID
1 NameB1 1
2 NameB2 1,10
3 NameB3 1025,1026
To select list data of table with ID. I used:
public static List<ListData> GetDataById(string id)
{
var db = Connect.GetDataContext<DataContext>("NameConnection");
var sql = (from tblB in db.TABLE_B
where tblB.LISTID.Contains(id)
select new ListData
{
Name= tblB.Name,
});
return sql.ToList();
}
When I call the function:
GetDataById("10") ==> Data return "NameB2, NameB3" are not correct.
The data correct is "NameB2". Please help me about that?
Thanks!

The value 10 will cause unintended matches because LISTID is a string/varchar type, as you already saw, and the Contains function does not know that there delimiters that should be taken into account.
The fix could be very simple: surround both the id that you are looking for and LISTID with extra commas.
So you will now be looking for ,10,.
The value ,10, will be found in ,1,10, and not in ,1025,1026,
The LINQ where clause then becomes this:
where ("," + tblB.LISTID + ",").Contains("," + id + ",")

Related

GORM query - how to use calculated field in the query and filter according to its value

Currently, I have a GORM query that calculates a counter for each table entry using a second table and returns the first table with a new field "locks_total" which doesn't exist in the original.
Now, what I want to achieve is the same table returned (with the new "locks_total" field) but filtered with "locks_total" = 0.
I can't seem to make it happen because it doesn't recognize this field in the table, what can I do to make it happen? is it possible to run the query and then execute the filter on the new result table?
This is how we currently do it-
txn := dao.postgresManager.DB().Model(&models.SecretMetadataResponse{})
txn.Table(dao.firstTableName + " as s").
Select("s.*, (SELECT COUNT(*) FROM " + dao.secondTableName + " as l where s.id = l.secret_id) locks_total ")
var secretsTotal int64
var metadataResponseEntries []models.SecretMetadataResponse
txn = txn.Count(&secretsTotal). // Saving the count before trimming according to the pagination parameters
Limit(params.Limit).
Offset(params.Offset).
Order(constants.FieldName).
Order(constants.FieldId).
Find(&metadataResponseEntries)
When the SecretMetadataResponse contains the SecretMetadata which is the same fields as in the table and the LocksTotal is the new calculated field that we want to have.
type SecretMetadataResponse struct {
SecretMetadata
LocksTotal int `json:"locks_total"`
}
Thanks in advance :)

Sql query 'IN ' operator is not work error?

I am using CI 'in'operator is not work sql error please check its and share valuable idea...
table
enter image description here
id | coach_name
------------------
9 | GS
------------------
10 | SLR
view and function
$coachID = explode(',',$list['coach']);
$coachname = $this->rail_ceil_model->display_coach_name($coachID);
show result
SLR
need result
GS,SLR
last query result here
SELECT coach_name FROM mcc_coach WHERE id IN('9', '10')
CI code
public function display_coach_name($coachID='')
{
$db2 = $this->load->database('rail',TRUE);
$db2->select('coach_name');
$db2->from('mcc_coach');
$db2->where_in('id',$coachID);
$query = $db2->get();
echo $db2->last_query(); die;
if ($query->num_rows() > 0):
//return $query->row()->coach_name;
else:
return 0;
endif;
}
You must provide an array to in operator so #coachId must be an array not a string
If you are writing this query
SELECT coach_name FROM mcc_coach WHERE id IN('9,10')
it means you are applying in operator on a single id which contains a comma separated value.
So, right query will be
SELECT coach_name FROM mcc_coach WHERE id IN('9','10')

Groovy SQL named list parameter

I want to use a keyset of a Map as a list parameter in a SQL query:
query = "select contentid from content where spaceid = :spaceid and title in (:title)"
sql.eachRow(query, [spaceid: 1234, title: map.keySet().join(',')]) {
rs ->
println rs.contentid
}
I can use single values but no Sets or Lists.
This is what I've tried so far:
map.keySet().join(',')
map.keySet().toListString()
map.keySet().toList()
map.keySet().toString()
The map uses Strings as key
Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Also, I don't get an error. I just get nothing printed like have an empty result set.
You appoach will not give the expected result.
Logically you are using a predicate such as
title = 'value1,value2,value3'
This is the reason why you get no exception but also no data.
Quick search gives a little evidence, that a mapping of a collections to IN list is possible in Groovy SQL.
Please check here and here
So very probably you'll have to define the IN list in a proper length and assign the values from your array.
title in (:key1, :key2, :key3)
Anyway something like this works fine:
Data
create table content as
select 1 contentid, 1 spaceid, 'AAA' title from dual union all
select 2 contentid, 1 spaceid, 'BBB' title from dual union all
select 3 contentid, 2 spaceid, 'AAA' title from dual;
Groovy Script
map['key1'] = 'AAA'
map['key2'] = 'BBB'
query = "select contentid from content where spaceid = :spaceid and title in (${map.keySet().collect{":$it"}.join(',')})"
println query
map['spaceid'] = 1
sql.eachRow(query, map) {
rs ->
println rs.contentid
}
Result
select contentid from content where spaceid = :spaceid and title in (:key1,:key2)
1
2
The key step is to dynamicall prepare the IN list with proper names of the bind variable using the experssion map.keySet().collect{":$it"}.join(',')
Note
You may also want to check the size if the map and handle the case where it is greater than 1000, which is an Oracle limitation of a single IN list.
It has worked for me with a little adaptation, I've added the map as a second argument.
def sql = Sql.newInstance("jdbc:mysql://localhost/databaseName", "userid", "pass")
Map<String,Long> mapProduitEnDelta = new HashMap<>()
mapProduitEnDelta['key1'] = 1
mapProduitEnDelta['key2'] = 2
mapProduitEnDelta['key3'] = 3
produits : sql.rows("""select id, reference from Produit where id IN (${mapProduitEnDelta.keySet().collect{":$it"}.join(',')})""",mapProduitEnDelta),
Display the 3 products (colums + values from the produit table) of id 1, 2, 3

Querying a LinqToSql result

Let's say I have a Persons table with two columns:
ID (Uniqueidentifier)
Name (NChar)
I need to get all my persons first:
Dim data = (From p In Persons Select p).ToList
Now that I got all persons in the data variable, is it possible to query this result using a string query? Like...
Dim filtered = (From p In data Select p).Where("Name Like '%John%').ToList
?
I need to build the query on the fly.
Thanks
var filtered = data.Where(a =>
SqlMethods.Like(a.name.ToString(), "%" +
Request.QueryString["search"] + "%"));
i use querystring as an example for dynamic value, and use it in sql like method,
which is similiar to sql like, in your case "request.querystring["search"] value is john"
Try this:
from p in data
where SqlMethods.Like(p.Name, "%"+parameter+"%")
select p;
parameter in your example should be John.

CDE: multiple select

I am trying to create a dashboard that consist from two components: CCC Bar chart and Multiple select component.
I use the multiply select component for assignment param value, which is using in the datasource. (MDX query):
SELECT
NON EMPTY {[Measures].[doc_count]} ON COLUMNS,
NON EMPTY {[Dimension Usage date_publish.Hierarchy date_publish].[date_publish].Members} ON ROWS
FROM [Docs]
WHERE CrossJoin({${param_hosts}}, {[event].[active]})
So if I set (multiply select component) property value array with pairs:
( {arg:[host].[news.com] value:news.com}, {{arg:[host].[somesite.com] value:somesite.com}} ), everything work perfect.
The parameter is bound to the component receives the correct value, for example: [host]. [News.com], [host]. [Somesite.com].
But if I try to fill the multiply select component from the datasource it become unworkable.
As DataSource, I use the sql over sqlJndi with query: SELECT distinct (host) as Id, concat ('[host]. [', Host, ']') as Value FROM docs_fact where dim_event_id = 1;
The result this query is a table:
id value
news.com | [host].[news.com]
somesite.com | [host].[somesite.com]
Parameter is assigned a value: news.com, somesite.com
Changing the properties of the Value as id only affects which of the fields (id or value) will be shown to the user, and the parameter's value is not affected.
Tell me please, is it possible to specify which of the columns to be used for display to the user and which of the columns to be used to generate results?
No, but you can change the dataset on the clientside using the postFetch function on the multi-select component.
function (dataset) {
for (var i=0; i < dataset.resultset.length; i++) {
var temp = dataset.resultset[i][0];
dataset.resultset[i][0] = dataset.resultset[i][1];
dataset.resultset[i][1] = temp;
}
return dataset;
}
Or similar