tags:

views:

46

answers:

6

Hi,

in a table "partners", i've a field "sites" which can contain values like 1,27,38,12

then, in a website which has ID n°27, i would like to get partners associated to this website.

I tried this : SELECT * FROM partners WHERE 27 IN (partners.sites)

It works if 27 is at the beginning of the string (eg: 27,1,128) but it doesn't work if 27 is in the middle (eg: 1,27,38,12)

Have you got any idea to manage this ?

Thanks. Cyril

+3  A: 

see the manual for find_in_set

ceteras
hidious solution
Alexander
Yeah, but it does exactly what Cyril asks for. It should be implemented as some kind of relation though, just as you pointed out. :)
André Laszlo
@Alexander, I admit. It's a hideous solution to a hideous question.
ceteras
A: 
SELECT * FROM partners WHERE partners.sites like '%27%'
Salil
No. This matches 127, too.
Tomalak
If at all, then like this: `WHERE CONCAT(',',partners.sites,',') like '%,27,%'` - but that's hideous.
Tomalak
Exactly, this is not a good solution
Cyril
+1  A: 

This doesn't make any sense

Why not make select * from partners where sites=27?

Or are you suggesting that sites is a varchar containing CSV? In this case this is totally wrong from any perspective. Do a one-to-many relationship in your database.

Alexander
A: 

Assuming sites is a field in the same table you're querying, you could try this:

SELECT * FROM partners WHERE sites LIKE %27;

SELECT * FROM partners WHERE sites LIKE 27;

Does that work?

webfac
not only does LIKE not help in this form, but also it expects 27 to be the only string there (which eliminates the need for LIKE) or at the end (why?)
Alexander
True, it was a badly thought out solution to an already messy problem. I'd have to agree with creating a one to many many to one relationship instead.
webfac
+1  A: 

You may want to use the FIND_IN_SET() function, because the IN() function will not expect a comma-separated string as an argument.

This does not work:

SELECT 27 IN ('1,27,5');
+------------------+
| 27 IN ('1,27,5') |
+------------------+
|                0 |
+------------------+

This works:

SELECT FIND_IN_SET(27, '1,27,5') > 0;
+-------------------------------+
| FIND_IN_SET(27, '1,27,5') > 0 |
+-------------------------------+
|                             1 |
+-------------------------------+
1 row in set (0.00 sec)
Daniel Vassallo
+1, tentatively. Solves the problem at hand but enables continued use of a really bad database design. I think what really has to be done is getting to rid of the CSV field and use a 1:n relation table for that.
Tomalak
@Tomalak: Yes, I agree.
Daniel Vassallo
A: 

I would have to agree that using relationships will not only be better practice, but will optimize your database request speeds as well, even if it's non noticeable, every bit counts.

So assuming you had a separate table called sites, you could do a call like follows:

SELECT * FROM partners WHERE pid IN (SELECT spid FROM sites WHERE siteid = 27);

Your relationship could then be something like:

-------------------------------------
PARTNERS
-------------------------------------
pid       | some field |
2         |            |
-------------------------------------

-------------------------------------
SITES
-------------------------------------
spid      | siteid     | surl
2         | 27         | http://...
-------------------------------------
webfac