How to store and then search through CSV in sql? - mysql

I know that I can use IN(1,2,3) to select items from an SQL database where their value is either 1, 2 or 3, but what if I have a value in MYSQL which is a string, and is equal to '1,2,3' and I want to select that value. As far as I know I have to do this:
SELECT whatever FROM wherever WHERE sqlvariable = '1' OR sqlvariable LIKE '1,%' OR `sqlvariable` LIKE '%,1,%' OR `sqlvariable` LIKE '%,1'
which is fine if I want to simulate 'IN' sort of in reverse. But lets say I want to select sqlvariable where it contains either 1 or 2, then I have to do this:
SELECT whatever FROM wherever WHERE sqlvariable = '1' OR sqlvariable LIKE '1,%' OR `sqlvariable` LIKE '%,1,%' OR `sqlvariable` LIKE '%,1' OR sqlvariable = '2' OR sqlvariable LIKE '2,%' OR `sqlvariable` LIKE '%,2,%' OR `sqlvariable` LIKE '%,2'
Now lets say I use PHP to generate the above queries and I'm looking to find sqlvariable where it contains a 1 2 4 66 34 33 22 44 or 992. It's going to take an awfully long time for this query to run.
I could do a bitwise implementation, but then I'm limited to only having about 60 different items or so which isn't enough.
Is there a faster way to utilize a CSV query like the above in sql? I suppose it's sort of like IN() but in reverse.

You can simplify your queries using FIND_IN_SET:
SELECT whatever
FROM wherever
WHERE FIND_IN_SET('1', sqlvariable)
OR FIND_IN_SET('2', sqlvariable)
This however will still require searching every row in the table. It would be better to redesign your database so that CSV formatted data is not required.
Update: Your existing design looks something like this:
groupname groupmembers
Group1 1,2,3
Group2 3,4
You should change it to something more like this:
groupid groupmember
1 1
1 2
1 3
2 3
2 4

Related

Define a custom ORDER BY order in mySQL using the LIKE word

How can I make a custom order where I sort the rows by NAME where the first rows' name has Bob in it followed by rows with name of Alex in it?
To explain what exactly I mean: I have made the following query to sort result if NAME = 'Bob' and if NAME = 'Alex':
SELECT * FROM table
ORDER BY CASE `NAME`
WHEN 'Bob' THEN 1
WHEN 'Alex' THEN 2
ELSE 3
END
But this only works when the NAME is exactly equal to Bob or Alex. I want to modify it to sort if the NAME has Bob or Alex in it, essentially if NAME LIKE '%Bob%' and NAME LIKE '%Alex%'. I tried something like the following but it does not work.
ORDER BY CASE `NAME`
WHEN LIKE '%Bob%' THEN 1
WHEN LIKE '%Alex%' THEN 2
ELSE 3
END
What is the correct syntax for this?
Use the other form of CASE where you specify a condition in WHEN rather than a value.
ORDER BY CASE
WHEN NAME LIKE '%Bob%' THEN 1
WHEN NAME LIKE '%Alex%' THEN 2
ELSE 3
END

Using Substring and like together

Hi I want to extract all values from the column Old_priceplan such that the outcome gives me 1 Mbps only
So if its xyz 20 Mbps it extracts 20 Mbps only and so and so forth.
also
is there a way i can use or in locate like locate('Mbps' or 'MB', old_priceplan?)
substring(old_priceplan, locate('Mbps',old_priceplan) - length(old_priceplan) - 4 , ifnull(locate('SL',old_priceplan),0) )
You can build a proper like condition eg:
assuming you value is store in a var
set #str = '1 Mbps';
then
select Old_priceplan
from my_table
where Old_priceplan like concat('%', #str, '%')
And as suggested by Lutz be sure you have a proper sanitized value assigned to var

Patern maching like Select Query

I have a table that contains this kind a structure of a column, how can I make select only from character 4 to 6 to ignore other character that are outside this boundary , I tried LIKE'%544%', RegExp. ect. ??
1 000544001
2 000054400
3 000544010
4 000344010
5 000544011
One way is to use substr():
where substr(col, 4, 3) = '544'
another is to use like:
where col like '___544%'
you can also use mid(col,start,length) statement
like this
select column1 from table1 where mid(column1,4,3);

MySQL Selecting Something with Array Information

Is there a way to do something like this?
SELECT * FROM tablename WHERE x CONTAINS "1"
Basically, I want to select data from the database where x contains a specific number. The thing is, the x column in any row could contain "1, 2, 3" and I want to select all those that contain 1, specifically 1, not 11 or anything that contains 1, but specifically a 1.
Here's an example:
id title x
-------------------
1 row1 1,22,3
2 row2 1,5
3 row3 5,91
4 row4 70
And I want my query to return rows 1 and 2. I don't want row 3, as the 1 is inside the number 91. I don't want row 4 because there's no 1 there either.
You can use the FIND_IN_SET function like so:
SELECT * FROM tablename WHERE FIND_IN_SET('1', x)
This will also get optimised to use bit arithmetic if you are calling it on a SET type.
You can try this:
SELECT * FROM tablename WHERE x REGEXP "(^|,)1(,|$)"
Ideally you'd normalize your 'x' column out to a separate table.
But... you could also hack it like this:
SELECT * FROM tablename WHERE x LIKE '%,1' OR x LIKE '1,%' OR x LIKE '%,1,%'
This basically just handles the three different cases where the "1" is the first, last or a middle element in your list. (note if you've got a space after your commas you'd change the last part to '%, 1,%'
EDIT: Actually Dmitriy's REGEXP is nicer, and a'r's FIND_IN_SET looks ideal.

Having a number in

Can someone give me a query that will return as a result rows ID 1 & 3?
ID Name Hidden
1 Mika 1,4,2
2 Loca 0
3 Nosta 4
4 Like 2
Something like this
SELECT * FROM table WHERE Hidden HAVING(4)
SELECT * FROM table WHERE FIND_IN_SET('4',Hidden);
docs for FIND_IN_SET
SELECT * FROM table WHERE CONCAT(',',Hidden,',') LIKE '%,4,%'
or you can avoid using LIKE like this
SELECT * FROM table WHERE INSTR(CONCAT(',',Hidden,','), ',4,') > 0
this will not get things like 40, 14, etc, but you need to make sure there are no spaces in the Hidden field (eg, 1, 4, 5 or update the concat and LIKE function accordingly.
SELECT * FROM table WHERE Hidden LIKE '%4%'
the % are wildcards.
Full Text Search might be a reasonable solution for this as long as you use the correct word breaks.
Either go with Full Text Search, as suggested, or
Spin the Hidden values off into a separate table, with the ID of current row.
Eg, Mika would have three entries in this table
ID = 1, Hidden =1
ID = 1, Hidden =4
ID = 1, Hidden =2
Then you could return results against this spin off table.
You may also want to consider normalizing the table and storing these "hidden" values in a separate table with an index on the apropriate column. Depending on the number of rows you have that would be much faster:
ID Hidden
1 1
1 4
1 2
3 4
4 2
and:
SELECT DISTINCT table.* FROM table, hidden_table WHERE table.ID = hidden_table.ID AND hidden_table.hidden = 4