Reputation: 1041
I'm having problems trying to query the following data:
id. | name | type
1. bob | a
2. sam | ab
3. jim | abc
4. sarah | ad
5. john | a
6. eve | bca
7. nikki | ca
I'm trying to write a MySQL query based on the following input:
a,
ac,
b*,
ac*
which I want to return the following names:
bob
john
sam
jim
eve
nikki
Breakdown:
a = bob, john
ac = nikki
b* = sam, jim, eve
ac*= jim, eve, nikki
Explained:
a = find results that are JUST a
ac = find results that contain ONLY an a AND c
b* = find results which contains a b
ac* find results that contain at least an a and a c
As can be seen the type column can contain type info in different orders (not always increasing).
I'm sure this could be done by splitting the type column into type_a
, type_b
etc etc and then just have a bool
in each one. But this could go up to z
and I don't want 26 extra cols on my table!
is this possible to do in a single query, if so any help would be appreciated!
Sorry about the title I had no idea what to call it
Upvotes: 0
Views: 182
Reputation: 125925
You can use regular expressions:
SELECT name FROM your_table WHERE
type RLIKE '^a+$' -- only 'a'
OR type RLIKE '^((a[ac]*c)|(c[ac]*a))[ac]*$' -- only & both 'a' AND 'c'
OR type RLIKE 'b' -- at least one 'b'
OR type RLIKE '(a.*c)|(c.*a)' -- at least 'a' and 'c'
;
Upvotes: 1
Reputation: 425593
-- ac*, ac, a, b*
SELECT *
FROM mytable
WHERE (
type RLIKE 'a'
AND type RLIKE 'c'
)
OR
(
type RLIKE 'a'
AND type RLIKE 'c'
AND NOT type RLIKE '[^ac]'
)
OR
(
type RLIKE 'a'
AND NOT type RLIKE '[^a]'
)
OR
(
type RLIKE 'b'
);
This won't use any indexes though.
If your table is MyISAM
, you can store types like this:
id name type
7 nikki a c
(note the spaces) and use FULLTEXT
functionality:
CREATE FULLTEXT INDEX fx_mytable_type ON mytable (type);
-- ac*
SELECT *
FROM mytable
WHERE MATCH(type) AGAINST '+"a" + "c"' IN BOOLEAN MODE);
-- ac
SELECT *
FROM mytable
WHERE MATCH(type) AGAINST '+"a" + "c"' IN BOOLEAN MODE);
AND NOT TYPE RLIKE '[^ ac]' -- note the space
Set @@ft_min_word_len = 1
for this to work.
Upvotes: 1