How to search from comma separated string in comma separated column mysql - mysql

I am working on a project where I have to code for job filters.
In this when I filters for salaries it sends salary id's in array like:
job_salary = array(
[0]=>3,
[1]=>4,
[2]=>5,
[3]=>6,
[4]=>7,
[5]=>8
)
and job in my jobs table contains multiple salaries using comma string.
id salary_ids
1 2,4,6
2 1,3,5
3 4,5
4 9,1
So if i search for value 3, and 5 in array form like
job_salary = array(
[0]=>3,
[1]=>5
);
It should return me the second and third row because these rows contain value 3 and 5.

Use it like below let me know if it works
$values=array("1","2","3");
foreach($values as $val)
{
$query="Select * from table_name where FIND_IN_SET('".$val."',column_name)";
$result=mysql_query($query);
$data=mysql_fetch_array($result);
$dbval[]=$data['column_name'];
}
print_r($dbval);

please try again like this
1).For Postgres MySQL :
SELECT FIND_IN_SET(5,userid) as result FROM department
2).For Postgres SQL :
select *
from TABLENAME f
where 'searchvalue' = ANY (string_to_array(COLOUMNNAME,','))
Example
select *
from customer f
where '11' = ANY (string_to_array(customerids,','))

Related

How to prepare the data so that I can count results by lowest selected hierarchy?

I have 4 dropdowns in the frontend, each representing a hierarchy level in the company:
Groups > Units > Departments > Teams
So users can select a group then it will only show units of that group and departments of that group and so on..
But users can also select multiple choices so they can select Group1, Group2, and it will show all the corresponding hierarchy "items".
I let the users select however they want - they can choose any department, any group and team and so on.
The goal is to count the number of results from the lowest of each selected hierarchy.
Example:
id
username
group
unit
department
team
1
user1
g1
u1
d1
t1
2
user2
g1
u1
d1
t2
3
user3
g3
u6
d12
t30
4
user4
g25
u54
d70
t88
The way I currently do it is to clean the selections so if for example a user clicked g1>u1>d1 and g25>u54>d70>t88, I build it with query builder like so:
foreach ($data as $row) {
$myQuery->orWhere(function($query) use ($filter) {
foreach ($filter as $column => $value) {
$query->where($column, '=', $value)
}
}
}
So the the raw SQL query would result in this:
SELECT * FROM table
WHERE (group='g1' AND unit='u1' AND department='d1')
OR WHERE (group='g25' AND unit='u54' AND department='d70' AND team='t88')
But I need to return the count for each, not the actual results.
I could do something like the following using UNION:
SELECT group
, unit
, department
, NULL as team
, COUNT(*) AS rows
FROM table
WHERE group='g1'
AND unit='u1'
AND department='d1'
GROUP
BY group
, unit
, department
UNION ALL
SELECT group
, unit
, department
, team
, COUNT(*) AS rows
FROM table
WHERE group='g25'
AND unit='u54'
AND department='d70'
AND team='t88'
GROUP
BY group
, unit
, department
, team
But I am not sure I can convert it do work with Query Builder.
Also, I feel like maybe the entire way I organize the data or build the initial query is wrong for the purpose.
Should I arrange the data differently completely? Or there is a way to achieve what I'm trying in this way?
As an idea, you can do something like this:
// prepare a query to operate with
$countQuery = DB::table('table');
// I don't know how do you get those filters, let's pretend it's like this
foreach ($filters as $index => $filter) {
// make a count subqueries for every bunch of filters and name it like filter0, filter1 etc.
$countQuery = $countQuery->addSelect(["filter".$index =>
function ($q) use ($filter) {
$q->selectRaw('COUNT(table.id)')
->from('table');
foreach ($filter as $column => $value) {
$q->where($column, '=', $value);
}
}]);
}
var_dump($countQuery->get());

Yii2 querybuilder sum from a one-many relation field

Help me understand how the sum function works, when I want to count from a relational table field.
The query is pretty simple. I have unitsOrdered table and unitsSent table. The relation is 1-n. So i want to count all sent units of the specific order. In this example order id=2;
In my db I have data.
unitsOrdered:
id
1
2
unitsSent:
id | order_id | units
1 | 1 | 5
2 | 2 | 2
My query is:
query = OrderedUnits::find()
->select([
'ou.*',
'sum(us.units) as alreadySent'
])
->joinWith('unitsSent us')
->where(['ou.id' => 2])
->orderBy('ou.id desc')
->groupBy(['ou.id'])
->all();
The result should be pretty clear:
id 2 = 2 units
However, my query returns:
id 2 = 10 units.
As I understand what i does is 5 * 2 = 10;
What is wrong with my query?
The relation is defined like this:
/**
* #return \yii\db\ActiveQuery
*/
public function getUnitsSent()
{
return $this->hasMany(UnitsSent::className(), ['order_id' => 'id'])
->from(['us' => UnitsSent::tableName()]);
}
Actual query:
'SELECT `ou`.*, sum(us.sent_units) as alreadySent FROM `ordered_units` `ou`
LEFT JOIN `units_sent` `us` ON `ou`.`id` = `us`.`order_id`
WHERE (`ou`.`id`= 2)
GROUP BY `ou`.`id`
ORDER BY `ou`.`id` DESC'
You should use the hash filter format this way ->where(['us.id' => 2])
and for get result 2 you need innerJoin (your raw sql show you have a left join) otherwise also the rows that not match are joined
query = OrderedUnits::find()
->select([
'ou.*',
'sum(us.units) as alreadySent'
])
->innerJoinWith('unitsSent us')
->where(['us.id' => 2])
->orderBy('ou.id desc')
->groupBy(['ou.id'])
->all();
and try check the real query executed using
echo $query->createCommand()->getRawSql();
and remeber that the selection of columns not aggregated and not mentioned in group by is not allowed in mysql starting for 5.7 ( and anyway is not a correct way to use group by in SQL)

What will be Mysql query for group by and order by dictionary style?

Trying to fetch data and print as like dictionary.
Table:
blog_tags
id name
1 atag1
2 atag2
3 dtag1
4 etag1
5 etag2
6 ctag1
7 ctag2
8 ctag3
9 ztag1
I want the data output as:
A
atag1
atag2
C
ctag1
ctag2
D
dtag1
E
etag1
etag2
Z
ztag1
Started with this:
select name from blog_tags order by name;
what will be mysql query for this?
Try something like this
select name
from (
select distinct upper(substring(name, 1, 1)) as name
from blog_tags
union all
select name
from blog_tags
)
order by name
Edit
If you want to get raw data for application level manipulation, I would suggest querying the db this way
select upper(substring(name, 1, 1)) as key,
name
from blog_tags
order by 1, 2
You can use the bellow query to achieve this as given below
select substr(name,1,1),group_conact(name) from blog_tags group by substr(name,1,1);
This query will group the name's by first character and will group concat the name's as comma separated. You can convert the result from your programming language to array
The output will be like given below
substr(name,1,1) group_conact(name)
A atag1,atag2
C ctag1,ctag2

Append string to a record's specified column after SELECT command

I have an sql command that returns me a list of duplicated items (in my MySQL database), only two columns, one for the duplicated value and one for the count of duplicated records.
SELECT title, COUNT(*) c FROM posts GROUP BY title HAVING c > 1
title c
---------------
title_1 2
title_a 2
title_b 2
I assume one result looks like this:(and it's an array of arrays)
objId title
------------
1 title_1
2 title_1
So my goal is to append a string to the second item of a result in the array of the duplicated record's like this:
objId title
------------
1 title_1
2 title_1_2
I've found a solution to update the record, but I don't have an idea how could I loop through the results that I get after the first sql command so I can't utilize it in practice.
UPDATE posts SET title = CONCAT(IFNULL(title,''), ' 2');
In pseudo code I would do something like this to create the new string for the title:
result[1].title = (oldTitleString," 2");
save result[1];
I'm new in sql and don't really know about the possibilities, maybe there would be an easier way to do it, so I would really appreciate if somebody could show me how can I get the second record from the duplicated item and extend it with another string.
My solution:
SELECT `objId`,`title`,
(SELECT CONCAT(`title`, '_', `po`.`objId`)
FROM `posts` `p`
WHERE `title` = `po`.`title` && `p`.`objId` < `po`.`objId` LIMIT 1) AS `title_custom`
FROM `posts` `po`
Here is sample fiddle:
http://sqlfiddle.com/#!9/a4164/8
Query looks like this:
select id, title,
concat(title,'_',
(select count(*) from posts p2 where p2.title = p1.title and p2.id <= p1.id)),
title,
count(*) c
from posts p1
group by title
having c > 1

MySQL Inner Query with a Where and Group by conditions in cakephp

i am having a table named Reports with
id report_id user_id
1 1 5
2 1 5
3 1 5
4 2 5
5 2 5
6 3 6
7 3 6
8 4 1
9 4 1
10 4 1
i am trying to write a Query such that user_id = 5 and to find how many reports he has created.(Answer should be of 2 )
i have a Wrote a Mysql Query as
select count(distinct report_id) from Reports where user_id=5
i m trying the same MYSQl sub Query inside the Foreach users loop where my 5 is from $user['User']['id'];
how to write the MYSQL Query above inside this for loop in cakephp Framework....
foreach($users as & $user):
echo "User id ".$user['User']['id'];
$user['User']['report_count'] = $this->Report->find('count',
array('conditions'=>array('Report.user_id'=>$user['User']['id'])));
endforeach;
$this->set('users', $users);
Please suggest me.......HOw to write the above Mysql Query in cakephp
You want to use the following functions GROUP BY and COUNT
Your query could look somewhat like this
select count(distinct report_id) from Reports where user_id=5
If this is a list of users you are showing in your application... you could significantly reduce the number of queries you are running.
eg. for 100 users you will be running 100 queries instead you can run a single single query to extract the user_id and count of reports by each user
select count(distinct report_id) as count,user_id from Reports where user_id IN (1,2) GROUP BY user_id;
OR if you want to run seperate queries for each user
select count(distinct report_id) as count,user_id from Report where user_id=5;
Try this:
$user['User']['report_count'] = $this->Report->find('count',
array( 'conditions' => array('Report.user_id' => $user['User']['id']),
'fields' => 'DISTINCT Report.report_id'
)
);
It should fetch all distinct report_ids for a given user_id, then count them. Basically, it should run the query:
SELECT DISTINCT report_id FROM Reports WHERE user_id=$user['User']['id']
(after substituting the value of $user['User']['id']), then count the number of rows in the result. Caveat: I don't use CakePHP in real life, I just read the documentation; your mileage may vary. As halocursed mentions, running a single SQL query on your own would be more efficient than calling find(...) for each user ID. You could also try:
$report_counts = $this->Report->find('list',
array( 'conditions' => array('Report.user_id' => array_map(create_function('$user', 'return $user["User"]["id"];'), $users)),
'group' => array('Report.user_id'),
'fields' => array('Report.user_id', 'COUNT(DISTINCT Report.report_id) AS report_count')
)
);
foreach ($users as &$user) {
$user['User']['report_count'] = $report_counts[$user['User']['id']];
}
However, I don't know if CakePHP will accept aggregate functions in the 'fields' parameter, and I don't know as though find('list', ...) will pick Report.user_id as the array index. If you're having problems with the latter, you could switch to a [find('all', ...)][3] call and loop over $report_counts rather than $users. I didn't take this approach because I don't know the structure of $users, such as how it's indexed.