Check whether any values in array match any values in json column - mysql

I have a problem of checking whether any values in an array match any values in json column which contains an array with a name.
suppose i have an array [25,36,45,52] and json column is {"values": [25,24,15]}.
I want to check whether any values in array match any of values in json column in xampp mysql. please provide a better solution of doing this. this image show table structure of my database
i have 4 tables.
user
profile
profile
jobs
user table (id,userid)
jobs table (id,user_id,skill_id)
skill table (id,job_id,)
profile table (id,user_id)
now i want to search all jobs that match some or at least one skills.
i have tried with this but this is giving all jobs with out skills filtered.
$jobs = Job::with(['user','profile'])->with(['skills' => function($query){
$query->whereJsonContains('skills->skills',[35]);
}])->where('jobs.is_completed',0);
please help me.

you can use where Clause easily for example you would like to get rows that match skills 35,54:
$users = DB::table('table')
-> whereJsonContains('skills->skills', [35,54])
->get();
for more details about how to querying json column check official docs :
https://laravel.com/docs/5.8/queries#json-where-clauses

Related

How to apply advance search query with multiple values and conditions

I have a view where user select fields to make an advance search, the fields are:
**name**- **age** - **location** - **isPaid** - **date_subscription**, **date_expiration**
the user might choose one column or make combinations of multiple columns, I am confused if I should use if statement to detect which columns are selected, and then run the query depends on the selected column, but this way I will need to set all the valid conditions, which mean set the all the valid combination. Is there an other way to execute such queries?
I was writing this query, but i stopped because i just realize how long it will be:
SELECT * FROM internetclientdetails icd INNER JOIN internetclient ic on ic.id = icd.icid WHERE
(icd.date_sub <=".$start_dateSubsc." and cd.date_sub >= ".$end_dateSubsc.")
OR
(icd.date_exp <=".$start_dateExp." and cd.date_exp >= ".$end_dateExp.")
OR
(
(icd.date_sub <=".$start_dateSubsc." and cd.date_sub >= ".$end_dateSubsc.")
AND
(icd.date_exp <=".$start_dateExp." and cd.date_exp >= ".$end_dateExp.")
)
OR
.
.
.
but this is too long to be write since i still have 4 left fields to set OR , AND operators
Generally you add some already query building library, which can construct valid SQL from the input you select.
There are a number of them, for example, Doctrine DB abstraction layer, Medoo and a number of others.
For example, in Medoo a rather complex query such as:
SELECT account,user_name FROM table
WHERE user_id IN (2,123,234,54) OR
email IN ('foo#bar.com','cat#dog.com','admin#medoo.in')
will be writen in PHP as:
$database->select("account", "user_name", [
"OR" => [
"user_id" => [2, 123, 234, 54],
"email" => ["foo#bar.com", "cat#dog.com", "admin#medoo.in"]
]
]);
So all you have to do when using medoo is to pass it the correct input from the form.
As regards your question about how the user selects different columns, you can use something like this:
$mapping=array("start_dateSubsc"=>"date_sub", "end_dateSubsc"=>"date_sub",...);
where you list all the possible fields for user to enter in webpage, which are mapped to the real database table column names.
Then you do something like this, when you process the page:
$wherequery["OR"]=array();
foreach ($mapping as $userfield => $dbfield)
{
if array_key_exists($userfield, $_REQUEST)
array_push($wherequery["OR"], $dbfield => $_REQUEST[$userfield]);
}
$database->select("your columns"),[ $wherequery ]);
This will work for fields that need to be = to what user said and where you must match any of the fields.
You would have a bit more to do with fields that can be in range, and process them seperately, as well as processing fields with "AND", but that depends on the range and possibilities of your actual fields.

Rails, MySql, JSON column which stores array of UUIDs - Need to do exact match

I have a model called lists, which has a column called item_ids. item_ids is a JSON column (MySQL) and the column contains array of UUIDs, each referring to one item.
Now when someone creates a new list, I need to search whether there is an existing list with same set of UUIDs, and I want to do this search using query itself for faster response. Also use ActiveRecord querying as much as possible.
How do i achieve this?
item_ids = ["11E85378-CFE8-39F8-89DC-7086913CFD4B", "11E85354-304C-0664-9E81-0A281BE2CA42"]
v = List.new(item_ids: item_ids)
v.save!
Now, how do I check whether a list exists which has item ids exactly matches with that mentioned in query ? Following wont work.
list_count = List.where(item_ids: item_ids).count
Edit 1
List.where("JSON_CONTAINS(item_ids, ?) ", item_ids.to_json).count
This statement works, but it counts even if only one of the item matches. Looking for exact number of items.
Edit 2
List.where("JSON_CONTAINS( item_ids, ?) and JSON_LENGTH(item_ids) = ?", item_ids.to_json, item_ids.size).count
Looks like this is working
You can implement a has many relation between lists and items and then access like this.
List.includes(:item).where('items.id in (?)',item_ids)
To implement has_many relation:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

correctly fetch nested list in SQL

I have a design problem with SQL request:
I need to return data looking like:
listChannels:
-idChannel
name
listItems:
-data
-data
-idChannel
name
listItems:
-data
-data
The solution I have now is to send a first request:
*"SELECT * FROM Channel WHERE idUser = ..."*
and then in the loop fetching the result, I send for each raw another request to feel the nested list:
"SELECT data FROM Item WHERE idChannel = ..."
It's going to kill the app and obviously not the way to go.
I know how to use the join keyword, but it's not exactly what I want as it would return a row for each data of each listChannels with all the information of the channels.
How to solve this common problem in a clean and efficient way ?
The "SQL" way of doing this produces of table with columns idchannel, channelname, and the columns for item.
select c.idchannel, c.channelname, i.data
from channel c join
item i
on c.idchannel = i.idchannel
order by c.idchannel, i.item;
Remember that a SQL query returns a result set in the form of a table. That means that all the rows have the same columns. If you want a list of columns, then you can do an aggregation and put the items in a list:
select c.idchannel, c.channelname, group_concat(i.data) as items
from channel c join
item i
on c.idchannel = i.idchannel
group by c.idchannel, c.channelname;
The above uses MySQL syntax, but most databases support similar functionality.
SQL is made for accessing two-dimensional data tables. (There are more possibilities, but they are very complex and maybe not standardized)
So the best way to solve your problem is to use multiple requests. Please also consider using transactions, if possible.

cakephp retrive data from one table excluding the associated tables

I am struggling with a basic problem. i am using cake php 2.5. i try to apply the find query in the company model and receiving all the data from companies and with its associations, but i only want to receive the data from company table and want to exclude the data from rest of relationships, can anyone help me with this. below are my queries.
$this->loadModel('Company');
$fields=array('id','name','logo','status');
$conditions=array('status'=>1);
$search_companies = $this->Company->find('first',
compact(array('conditions'=>$conditions,'fields'=>$fields)));
print_r($search_companies);die();
echo json_encode($search_companies);die();
With out seeing your data output, I am just going to take a stab at the problem.
Inside your $search_companies variable you are getting a multidimensional array probably with the other values of the other tables.
Why not just select the one array:
$wantedData = $search_companies['Company'];
// The key Company (which is the model) should be the data you are wanting.
Try setting model's recursive value to -1
$this->Company->recursive = -1;
$search_companies = $this->Company->find('first',
compact(array('conditions'=>$conditions,'fields'=>$fields)));
With this you will not fire the joins queries and therefore you only retrieve model's information.
Cakephp provide this functionality that we can unblind few/all associations on a any model. the keyword unbindModel is used for this purpose. inside the unblindModel you can define the association type and model(s) name that you want to unblind for that specific association.
$this->CurrentModelName->unbindModel(array('AssociationName' => array('ModelName_Youwwant_unblind')));

SQL Alchemy return list of ids

I am using SQL Alchemy and I want to return a list of Document Ids. The Ids are the primary key in the documents table. My current query returns a list of tuples.
userDocs = session.query(Document.idDocument).filter(Document.User_idUser == user.idUser).all()
The reason I want a list of ids is so that I can search another table using in_(userDocs).
So another solution would be to be able to search using tuples. I am currently returning nothing from my second query using userDocs.
Thank you!!
You don't need to do an intermediate query, you can do this all in one shot!
things = session.query(Things) \
.join(Thing.documents) \
.filter(Document.User_idUser==user.idUser)
You just query on the properties of the Document through its relationship() on the intended entity.