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
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
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.
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?
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
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.