mysql select data from a multivalue attribute - php

How can I run a select query on a multivalue attribute? Does mysql have a function do select certain data from a multivalue field? Much help is appreciated. Here's a sample of the problem:
Table
userid groups
-------------------
2 2,3,5
4 1
9 2,5,10
datatype is char(250) for groups
I want to do a query to select all userids that belong to group 5, in this example it would be userid 2 and 9. So:
userid
------
2
9
Any way to go about it with a mysql query? or with php/mysql?

In case the groups datatype is SET
You can use
SELECT * FROM users WHERE FIND_IN_SET('5', groups);
UPDATE
In case of char or varchar. You can use this
SELECT * FROM users
WHERE
groups LIKE '5,%'
OR groups LIKE '%,5'
OR groups LIKE '%,5,%'
OR groups = '5'

This is ugly, but if you want to do it completely in MySQL, you could do:
SELECT *
FROM users
WHERE groups LIKE '%,5,%'
OR groups = '5'
OR groups LIKE '%,5'
OR groups LIKE '5,%'
You'd be better off having a separate table with one group per row and a reference back to the user. You could do a join with a much simpler condition with that schema.
SELECT users.*
FROM users
INNER JOIN users_groups ON (users.user_id = users_groups.group_id)
WHERE users_groups.group_id = 5

Related

SQL query that considers data from other table

I have two tables:
employees:
id, CMS_user_id, practice_group_id, ...
and
users:
id, level, ...
I want to select all employees where practice_group_id is 2 but only if the respective user has a level of 1 according to the users table. I researched and I have a feeling it has something to do with the UNION keyword eventually, but I can't quite figure it out.
In "human language", the query would be like this:
"select all from employees where practice_group_id is 2 and then check the CMS_user_id from the employee and check in the table users whether the respective user with the id that equals CMS_user_id has a level of 1"
A JOIN will match the corresponding rows between two tables. Then, filtering can be done using WHERE.
For example:
select e.*
from employees e
join users u on u.id = e.CMS_user_id
where e.practice_group = 2 and u.level = 1

Select rows where any of field's values matches values from array

I have a pretty complicated task. I need to select rows which match any of an array's value - BUT the field contains many comma-seperated values as well.
$teamlist = "25,26,27,28,29,30"
MYSQL-Row 1 = "26,29,31,35,36"
MYSQL-Row 2 = "30,31,32,36,39"
MYSQL-Row 3 = "31,35,36,37,38"
MYSQL-Row 4 = "23,26,29,30,31"
As result Rows 1,2 and 4 should be selected.
I tried something like:
mysqli_query($con,"SELECT * FROM user_meta WHERE team IN '".$ids."'");
But that only works if the fields only contain one id, not multiple. I am stuck. Any ideas?
Thanks!
You could pass your parameters as a derived table and then use find_in_set() to search the csv column:
select t.*
from mytable t
inner join (
select 25 team_id
union all select 26
union all select 27
...
) x on find_in_set(x.team_id, t.team)
This leaves you with the work of building the derived table from your application. In very recent versions of MySQL, the VALUES() statement makes the task a litte easier:
select t.*
from mytable t
inner join (values row(26),row(27), ...) x(team_id)
on find_in_set(x.team_id, t.team)
However, you should not be storing lists in a database columns. This is hurtful in many ways, as explained in this famous SO answer. You should be storing each value of the each list on a separate row.

SELECT loop within SELECT loop [duplicate]

This question already has answers here:
MySQL Results as comma separated list
(4 answers)
Closed 4 years ago.
I have a PHP/MySQL scenario where I want to display a list of events but also show all users assigned to an event. In MySQL I have an events, eventusers and users tables.
I can SELECT event_id, event_name FROM events then loop through results in PHP and then SELECT user_id FROM eventusers WHERE event=[event_id] in each result loop to get that particular event's users.
I am wondering if there is way to do this in one single SQL query (and it's also performance decent) so I get data from the events table as well as all the user IDs attached to the event from the eventusers table. Something like:
event id | event name | Users from eventusers table
------------------------------------------
1 | Soccer match | 3,56,79
2 | Cycling | 46,77,88,126,78
You should make use of a JOIN statement, which merges your tables:
SELECT column_name(s)
FROM table1
INNER JOIN table2 ON table1.column_name = table2.column_name;
In your case, you should do something like:
SELECT event_name, user
FROM events
INNER JOIN eventusers
ON events.event_id = eventusers.event_id
I hope this is helpful for you
You can use the join function:
select * from
table1 JOIN table2
ON table1.pk=table2.fk
and then add the condition
where table1.column= something
however you need to have both tables joined with a column (.pk and .fk), in this case it could be the eventuserid
select * from
events JOIN eventusers
ON events.eventuserid=eventusers.userid
where event.id= [event_id]
Also you can subtitue the * with the columns you'll need: tablename.column and youll only get those column values in return
I'm sorry I dont understand the second part about the CSV file, can you clarify?

Mysql SELECT name where all rows with the name have certain values

How would I write a query that would select the name of a person (a column in the row) given that they have enough rows to meet all conditions?
For example, I have a database set up like so:
name permission_id
Bob 1
Bob 2
Jerry 3
Jerry 1
Jose 2
Billy 1
Billy 2
How would I only select the people that have permission id 1 and 2? In other words, I would like a query that checks every person by name to see if they have all the permissions requested.
In this example if I was to check for all users to who have permission 1 and 2 I should get Bob and Billy as a return value.
Here is my current query:
$this->db->select('center_user_permissions.id, center_users.first_name, center_users.last_name');
$this->db->from('center_user_permissions');
$this->db->where_in('permission_id', $permission_ids);
$this->db->join('center_users', 'center_users.center_id = center_user_permissions.center_id');
Currently this query returns anybody who has either permission id 1 or 2. I need it to be 1 AND 2. But I know I can't simply make two wheres because one particular row can't have both permission ids, but the query must check all rows for the specified ids.
I believe I would need a SELECT statement inside of my where? Can anybody tell me if I'm thinking correctly? Thanks.
You can use a in clause an an having for check that the user has both the permission
select name
from center_user_permissions
where permissions_id in (1,2)
group by name
having count(*) = 2
I'm not sure how to build this query in CodeIgniter, but you could INNER JOIN for each permission ID you want the user to have:
SELECT center_users.center_id, center_users.first_name, center_users.last_name
FROM center_users
INNER JOIN center_user_permissions AS p1 ON p1.center_id=center_users.center_id AND p1.permission_id=1
INNER JOIN center_user_permissions AS p2 ON p2.center_id=center_users.center_id AND p2.permission_id=2
You could check for more permissions by adding a INNER JOIN for each additional permission you wanted to require.
MySQL's GROUP BY and HAVING
Not user what kind of DB interface you're using in $this->db, but it may make things a little tricky. If I start with a raw SQL query:
SELECT
center_user_permissions.id,
center_users.first_name,
center_users.last_name
FROM center_user_permissions
LEFT JOIN center_users
ON center_users.center_id = center_user_permissions.center_id
WHERE center_user_permissions.permission_id in (1,2)
Group by name, where count of permission_id is > 1
This will group rows by first_name (so you'll only get one row for each unique name). Doing do allows you to run aggregate functions (SUM(), MAX(), COUNT()) against the rows that were "grouped" into a single row.
SELECT
center_user_permissions.id,
center_users.first_name,
center_users.last_name
FROM center_user_permissions
LEFT JOIN center_users
ON center_users.center_id = center_user_permissions.center_id
GROUP BY center_users.first_name
WHERE center_user_permissions.permission_id in (1,2)
HAVING COUNT(center_user_permissions.permission_id)>1
select distinct(name),.. as name from 'center_user_permissions',center_users where
center_users.center_id = center_user_permissions.center_id and permissions_id in (1,2)
substitute .. with your other fields and put in distinct the value that you want to be unique

SQL query for Selecting from Multiple Tables in single database

I am having 3 tables (c19 , c19b2, g26) in a database
I want to write a SQL Query to search and display all fields of the matched record.
I am using following query:
$query = "SELECT * FROM c19,c19b2,g26 WHERE armyno LIKE '%$searchTerm%'";
But it only works for table c19,
Data from the other 2 tables is not fetched.Each table has a field armyno
Please help me with this
Thank you.
Alright, you are not looking for a JOIN, but a UNION.
SELECT * FROM c19 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM c19b2 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM g26 WHERE armyno LIKE '%$searchTerm%'
That will let you query all three tables at the same time.
Which DB are you using? This would have worked in SQL Server. However, notice you are doing a cross join of every record to every record... usually you only want to match some records by restriction of a matching key, for example:
select
*
from a
left join b on b.somekey = a.somekey
left join c on c.someotherkey = b.someotherkey
In SQL server you can just say *, but I'm taking it that in your DB engine that didn't work, so try specifying which table. This may in some environments require aliasing as well:
select
a.*,
b.*,
c.*
from tableA as a
left join tableB as b on b.somekey = a.somekey
left join tableC as c on c.someotherkey = b.someotherkey
Generally, you should see the columns from the first table, followed by the columns from the second table, followed by columns from the third table for a given row. If you wanted to get all columns from all tables, but separately, then that would be 3 separate selects.
Lastly, if all 3 tables have "armyno" then I'd expect it to throw an ambiguous field error. In such case you'd want to specify which table's "armyno" field to filter on.

Categories