How to insert a character into a string in sql - mysql

So, I have a table that I wish to look like this
id | path
----------- -------------------------
000000 | images/0/0/0/0/00.jpg
000001 | images/0/0/0/0/01.jpg
000002 | images/0/0/0/0/02.jpg
where id is an auto_increment number and path is a string. I wish to make the column path be auto_generated but I couldn't find a SQL function to do that. If I were to use Python, I can easily calculate path with this expression
ID = 1
path='images/'+'/'.join(str(ID).zfill(6))[::-1].replace('/','',1)[::-1]+'.jpg'
However, I have no idea how to do that with SQL. I understand that I can retrieve the ID from database and then use a script to calculate the path, but I think it may be better just to cache all the results in the database so that my script can work faster.
Update:
I can, of course, write a script to handle this, be it a js, Python or PHP. But since I don't know what the id would be before I insert a row, I need to do an INSERT, then SELECT, to find out the id; then I have to UPDATE the calculated path. In total this will be three queries. What I wanted to do was to simplify the whole thing into one query, for I'm worrying about performance issue.

I don't know if I understand correctly but it looks like you want that the auto_generated path looks like a id but separated by "/". If it's this why don't you use php str_split to convert id string in other strings, and this way you can generate the path automatically.
For example:
<?php
//first you must do a mysql select to display all fields
//this define your string
$str = $id;
//this cut string with a limit of 1 character
$arr = str_split($str, 1);
//define a string with the path format you want
$path = "images/$arr[0]/$arr[1]/$arr[2]/$arr[3]/$arr[4]/$arr[5]$arr[6].jpg";
//now do a mysql update
UPDATE db_name SET path=$path WHERE id=$id;
?>
And the result will be a path updated to, where id = 000001, images/0/0/0/0/01.jpg

Related

In mysql where clause bigint showing unexpected result

Hope you all are doing well.
Today morning I was writing some sql query and I found a situation where I need your suggestion on that so here is the situation:
I've a table in mysql called users it has id column which is bigint
now when I'm trying to extract data with a query like :
select * from users where id = 123
in this case it'll show the result for user 123
now the situation here is if I run the same query like:
select * from users where id = 123b
now the issue here is it is still giving me the data for user 123
need your suggestion guys on the same, I did some R&D on the same but didn't found much usefull.
Thank you
Your question is tagged with mysqli which means you are using PHP to build your query. If you pass the string 123b as an integer, PHP will keep the leading digits:
var_dump((int)'123b');
# output: int(123)
MySQL then execute your query with this well formed integer 123.
If you execute a raw SQL query using any tool of your choice you should get an error like the following:
Unknown column '123b' in 'where clause'
This is because 123b cannot be an integer as it contains a letter, and isn't a string as it has no string delimiters.
Note that MySQL can still interpret strings without delimiters like hexadecimal values. For example, 0x31323362 is a valid string value for 123b and does not need quotes around it.

SQL get row by int | string

Im little bit stucked with my SQL query.
I've got a table with rows that can be identified by id or hash string...
id
short
title
1
asdadasdsd
foo
2
1qweqweqwe
bar
3
yxcyxcyxcy
baz
So SQL is quite easy...
SELECT * FROM table WHERE id=<identifier> OR hash=<identifier>
What I found out is that when my identifier is hash and begins with number which could be found in the id column, MYSQL returning me "wrong" row.
For example when my identifier is "1qweqweqwe" result is row 1.
I think the reason for that is it converts my hash string into integer maybe? Is there a way how to disable this behaviour?
Or the only way is to regenerate all hashes into new formats without numbers in it?
Thank you for any clarification :)
Petr
No, you do not have to regenerate the hashes. If both the id and hash match and you prefer
to pull row based on hash, then you could have the hash as the first match column condition. Basically it goes with the first match condition that is found to be true.
Also, I suppose you are already adding quotes to the hash string in the query. If not please do, as it will validate as a string then.
SELECT * FROM table WHERE hash='<identifier>' OR id=<identifier>
You seem to be passing the identifier in as a string -- because it is. But then you are comparing to a number (the id) and the string parameter is converted to a number. MySQL does so by converting the leading digits, if any.
I don't like the logic of passing in a string for an identifier, so I would really suggest that you fix the calling logic and call either:
WHERE id = <int identifier>
or:
WHERE hash = <string identifier>
But if you want to keep your current version, you can convert to a string:
WHERE CAST(id AS CHAR) = <identifier> OR hash = <identifier>

Select a part of a string in MySQL

I have a MySQL table with a string column as,
ID String
----- -----------------------------------------
1 {"Type":"new", "Node":"{Status=New, Properties=[{PropertyValue=Samp, PropertyRefernceTypeID=1, PropertyTypeID=26}, {PropertyValue=25, PropertyRefernceTypeID=1, PropertyTypeID=33}]}"}
2 {Type":"new", "Node":"{Status=New, Properties=[{PropertyValue=25, PropertyRefernceTypeID=1, PropertyTypeID=33}, {PropertyValue=168-3, PropertyRefernceTypeID=1, PropertyTypeID=103}]}"}
Now how can I select only the PropertyValue of PropertyTypeID=33 in MySQL select Query? It is possible by using substring() method only if the length of all the strings are equal but in my case the length may vary for different ids.
This is why it is considered bad practice to store JSON, serialized arrays/objects, or just multiple values in a database field, unless for some reason you would never need anything inside it.
The field should always be atomic. You should follow database normalization guidelines.
Therefore your database should be something like:
ID | PropertyValue | PropertyReferenceTypeID | ProductTypeID
Then you would never have this problem, you would just do SELECT PropertyValue FROM Properties WHERE ID=1
But for now, to avoid this trouble, if you are using an app language, just get the string and decode it. For example, in PHP:
$array = json_decode($str);
$PropertyValue = $arr['Node']['Properties']['PropertyValue'];
P.S. Your json still isn't completely valid with it's nesting.

MySQL Select Row Where Column Contains a Value

I have tried using 'LIKE' but it runs into problems which i will explain below.
i have a string column that looks like any of these.
"1010, 2020, 3030"
"1010"
""
I want to be able to see if this string contains a single ID. e.g 2020. if it does then return the row. I tried using like but if the id is 20 it will return the row because 2020 contains 20.
Selecting the entire db and then using a delimiter to go through all the strings will take far too much time. Is it possible to implement this?
This is why you don't store multiple values in a single field. Because your bad design, this is the query structure you'll have to use EVERY SINGLE TIME to compensate for it:
WHERE
foo = 2020 // exact match, only value in field
OR foo LIKE '2020,%' // value is at start of field
OR foo LIKE '%,2020,%' // value is somewhere in the middle of the field
OR foo LIKE '%,2020' // value is at the end of the field
Or you could have had a properly normalized design, and just done
WHERE childtable.foo = 2020
and be done with it.
First, you should not store lists of things in string variables. SQL has a very nice data structure for lists. It is called a table. Each row in such a table would have an id and one value from the list.
That said, sometimes you are stuck with data like this. In that case, you can use find_in-set():
where find_in_set('20', replace(stringcolumn, ', ', ',')) > 0;
You can also do the logic with like, but MySQL has the convenient built-in function for this.
EDIT:
If you want to do this with like:
where concat(',', stringcolumn, ',') like '%,20,%'
Note that the delimiters "protect" the values, so 20 is not confused with 2020.

Creating variables and reusing within a mysql update query? possible?

I am struggling with this query and want to know if I am wasting my time and need to write a php script or is something like the following actually possible?
UPDATE my_table
SET #userid = user_id
AND SET filename('http://pathto/newfilename_'#userid'.jpg')
FROM my_table
WHERE filename
LIKE '%_%' AND filename
LIKE '%jpg'AND filename
NOT LIKE 'http%';
Basically I have 700 odd files that need renaming in the database as they do not match the filenames as I am changing system, they are called in the database.
The format is 2_gfhgfhf.jpg which translates to userid_randomjumble.jpg
But not all files in the database are in this format only about 700 out of thousands. So I want to identify names that contain _ but don't contain http (thats the correct format that I don't want to touch).
I can do that fine but now comes the tricky bit!!
I want to replace that file name userid_randomjumble.jpg with http://pathto/filename_userid.jpg So I want to set the column user_id in that row to a variable and insert it into my new filename.
The above doesn't work for obvious reasons but I am not sure if there is a way round what I'm trying to do. I have no idea if it's possible? Am I wasting my time with this and should I turn to PHP with mysql and stop being lazy? Or is there a way to get this to work?
Yes it is possible without the php. Here is a simple example
SET #a:=0;
SELECT * FROM table WHERE field_name = #a;
Yes you can do it using straightforward SQL:
UPDATE my_table
SET filename = CONCAT('http://pathto/newfilename_', userid, '.jpg')
WHERE filename LIKE '%\_%jpg'
AND filename NOT LIKE 'http%';
Notes:
No need for variables. Any columns of rows being updated may be referenced
In mysql, use CONCAT() to add text values together
With LIKE, an underscore (_) has a special meaning - it means "any single character". If you want to match a literal underscore, you must escape it with a backslash (\)
Your two LIKE predicates may be safely merged into one for a simpler query