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.
Related
I need to make a select that returns objects with IDs in specified array. But it would be very helpful if I could get in return the same object as many times as it was specified in closure. Even that this object is only once in database. For example
SELECT * FROM `T` WHERE `id` IN (1, 1, 2)
I would like it to return 3 rows - 2x first one. And it's important for me that these results are in order that was specified in closure. Is this possible with MYSQL?
You could do something like this:
SELECT * FROM T WHERE item_id = 1
UNION ALL
SELECT * FROM T WHERE item_id = 1
UNION ALL
SELECT * FROM T WHERE item_id = 2
Using union all, you concatenate all the statements (which only return 1 row)
You can also write.
Because UNION ALL always uses a memory table to hold the results.
You can keep the memory table much smaller when you only define numbers.
I also assume that the column id is a auto_incremented column with a primary key.
Without a index on the id column joining isn't a great idea.
SELECT
T.*
FROM (
SELECT
1 AS number
FROM DUAL
UNION ALL
SELECT
1 AS number
FROM DUAL
UNION ALL
SELECT
2 AS number
FROM DUAL
)
AS numbers
INNER JOIN
T
ON
T.id = numbers.number
ORDER BY
numbers.number ASC
I have two mysql tables. And essentially two queries (one to each table) that I want to combine within a single SQL Query. Seems like it should be easy (kind of like an inner Join) But inner join is DUPLICATING non-uniqe values from table 2 into my results array... I dont want them duplicated... I want those duplicates from table/query 2 combined into the result record of query1
Query 1 Gets records from table 1. Results are unique. (one ID returns one record) It's simply returning all fields on records where an ID is equal to one of my conditions. [Im using IN instead of a bunch of OR's)
$sid = "'M-179','M-242','M-231','Q-2thru5'" ;
$query = "SELECT * FROM table1 WHERE IN ($sid)`
Query 2 gets records from table 2. But results are NOT unique. One ID can return many records.
$query2 = "SELECT extra_data, pub_url FROM table2 WHERE IN ($sid)";
So I want EACH extra_data & pub_url field from ALL returned records just slapped onto the end of the query 1 result. Am I making sense? So the result would look something like this...
[0] => Array
(
* all my returned fields from the
record returned by query 1 here
$row['extra_data']
$row['pub_url'] <-returned record from query 2
$row['extra_data']
$row['pub_url'] <-another returned record from query 2
$row['extra_data']
$row['pub_url'] <-any another returned
record from query 2, etc..
)
What do you mean by combining the result?
Do you want the results from query2 to appear in the same
relevant rows but just extra columns, or you want them to
appear as new rows.
For the first case, you will have to use JOIN.
But I have a feeling that what you want to do is the second
case. In this case, you will have to use UNION. Note, however,
that in this case the columns of the two queries must match. So
the union of two queries would look like this:
-- pseudo code only
SELECT extra_data, pub_url FROM table1 WHERE IN ($sid)
union
SELECT extra_data, pub_url FROM table2 WHERE IN ($sid)
Try something similar to this, which would join the results of table 1 to table 2 on the column containing the sid value.
SELECT a.*, b.extra_data, pub_url
FROM table1 a
left outer join table2 b on a.sid = b.sid
WHERE a.sid IN ($sid)
I have used mysql DISTNCT keyword for one of my mySQL query for avoid duplication of data displaying on search box.
But when I add multiple column names on SELECT it doesn't work.
Please advice how to proceed.
$query = "
SELECT * FROM (
SELECT DISTINCT b.title,b.id, b.metakey
FROM categories b
WHERE b.title like '%".$searchc."%' AND b.parent_id BETWEEN 84 AND 107 AND b.level=3 ORDER BY LOCATE('".$searchc."', REPLACE(b.title, ' ', '')), b.title
) CLASS_CAT
UNION ALL
SELECT * FROM (
SELECT DISTINCT a.title, a.id, a.title as metakey
FROM content a join
categories b
on a.categories_id = b.id
WHERE REPLACE(a.title, ' ', '') like '%".$searchc."%'
AND b.parent_id BETWEEN 84 AND 107 AND b.level=3
) CLASS_ITEM
";
SELECT DISTINCT will remove duplicates from the one SELECT statement. UNION ALL directs the system to not look for duplicates between the two sets you are combining (each SELECT).
Use UNION (without ALL) instead. Note that removing the check for duplicates is faster, so if you know a set you're querying is unique, skip the dup check.
Also note that by row duplicates I'm referring to every column in every row. If any column makes a row unique it will appear in the result set. If you only want some columns to be unique you'll need to GROUP BY and aggregate the other columns (e.g. GROUP_CONCAT) or use additional queries to get other related data.
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
I have a rather complex join query, whose results I only care about when there is a single distinct Table_ID value in the result. For example, if there were multiple values for Table_ID, say 1 and 2.. I would want 0 rows returned.
I was thinking of doing this by adding WHERE COUNT(DISTINCT Table_ID) = 1. Is that the best way to go about this? Doing this through LIMIT doesn't seem possible because that would limit the number of rows I get returned from other tables beyond the one I intend to limit.
Using PHP/MySQL.
I did this once by grouping on the Table_ID and then counting the number of items in the group. Something like:
SELECT *, COUNT(*) AS num FROM `myTable` GROUP BY `Table_ID` HAVING num = 1
More info: http://www.java2s.com/Code/SQL/Select-Clause/UseCOUNTGROUPandHAVING.htm