Select integer column as corresponding letter of the alphabet - mysql

I have an int column that contains values no larger than about 20. I want to select as its corresponding upper case letter of the alphabet:
1 = A
2 = B
3 = C
...
I don't care what happens after Z because the column doesn't contain larger values. Is there a simple way to do this with a SQL query, to convert to a single-byte character like this?

Add 64 to your integer and you have the ASCII value of the letter you want.
mysql> select CHAR(1+64);
+------------+
| CHAR(1+64) |
+------------+
| A |
+------------+
Read https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_char

Another alternative specific to MySQL using elt
select elt(col,'A','B','C','D','E','F',...);
Demo

Related

MySQL - split column into multiple rows with a delimiter

I came across an old post and tried the code with a project that I am working on, and it worked, but I am still confused as to why, could anyone here please unpack the logic behind the code here? I am specifically referring to this fiddle.
I understand substring_index, but not sure what "numbers" does, as well as the char length calculations.
Thanks in advance.
The numbers table is a way to create an ad hoc table that consists of sequential integers.
mysql> SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4;
+---+
| n |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
+---+
These numbers are used to extract the N'th word from the comma-separated string. It's just a guess that 4 is enough to account for the number of words in the string.
The CHAR_LENGTH() expression is a tricky way to count the words in the command-separated string. The number of commas determines the number of words. So if you compare the length of the string to the length of that string with commas removed, it tells you the number of commas, and therefore the number of words.
mysql> set #string = 'a,b,c,d,e,f';
mysql> select char_length(#string) - char_length(replace(#string, ',', '')) + 1 as word_count;
+------------+
| word_count |
+------------+
| 6 |
+------------+
Confusing code like this is one of the many reasons it's a bad idea to store data in comma-separated strings.

Mysql query like number greater than x

I have a field for comments used to store the title of the item sold on the site as well as the bid number (bid_id). Unfortunately, the bid_id is not stored on its own in that table.
I want to query items that have a number (the bid_id) greater than 4,000 for example.
So, what I have is:
select * from mysql_table_name where comment like '< 4000'
I know this won't work, but I need something similar that works.
Thanks a lot!
Just get your bid_id column cleaned up. Then index is.
create table `prior`
( id int auto_increment primary key,
comments text not null
);
insert `prior` (comments) values ('asdfasdf adfas d d 93827363'),('mouse cat 12345678');
alter table `prior` add column bid_id int; -- add a nullable int column
select * from `prior`; -- bid_id is null atm btw
update `prior` set bid_id=right(comments,8); -- this will auto-cast to an int
select * from `prior`;
+----+-----------------------------+----------+
| id | comments | bid_id |
+----+-----------------------------+----------+
| 1 | asdfasdf adfas d d 93827363 | 93827363 |
| 2 | mouse cat 12345678 | 12345678 |
+----+-----------------------------+----------+
Create the index:
CREATE INDEX `idxBidId` ON `prior` (bid_id); -- or unique index
select * from mysql_table_name where substring(comment,start,length, signed integer) < 4000
This will work, but I suggest create new column and put the bid value in it then compare.
To update value in new column you can use
update table set newcol = substring(comment,start,length)
Hope this will help
There is nothing ready that works like that.
You could write a custom function or loadable UDF, but it would be a significant work, with significant impact on the database. Then you could run WHERE GET_BID_ID(comment) < 4000.
What you can do more easily is devise some way of extracting the bid_id using available string functions.
For example if the bid_id is always in the last ten characters, you can extract those, and replace all characters that are not digits with nil. What is left is the bid_id, and that you can compare.
Of course you need a complex expression with LENGTH(), SUBSTRING(), and REPLACE(). If the bid_id is between easily recognizable delimiters, then perhaps SUBSTRING_INDEX() is more your friend.
But better still... add an INTEGER column, initialize it to null, then store there the extracted bid_id. Or zero if you're positive there's no bid_id. Having data stored in mixed contexts is evil (and a known SQL antipattern to boot). Once you have the column available, you can select every few seconds a small number of items with new_bid_id still NULL and subject those to extraction, thereby gradually amending the database without overloading the system.
In practice
This is the same approach one would use with more complicated cases. We start by checking what we have (this is a test table)
SELECT commento FROM arti LIMIT 3;
+-----------------------------------------+
| commento |
+-----------------------------------------+
| This is the first comment 100 200 42500 |
| Another 7 Q 32768 |
| And yet another 200 15 55332 |
+-----------------------------------------+
So we need the last characters:
SELECT SUBSTRING(commento, LENGTH(commento)-5) FROM arti LIMIT 3;
+-----------------------------------------+
| SUBSTRING(commento, LENGTH(commento)-5) |
+-----------------------------------------+
| 42500 |
| 32768 |
| 55332 |
+-----------------------------------------+
This looks good but it is not; there's an extra space left before the ID. So 5 doesn't work, SUBSTRING is 1-based. No matter; we just use 4.
...and we're done.
mysql> SELECT commento FROM arti WHERE SUBSTRING(commento, LENGTH(commento)-4) < 40000;
+-------------------+
| commento |
+-------------------+
| Another 7 Q 32768 |
+-------------------+
mysql> SELECT commento FROM arti WHERE SUBSTRING(commento, LENGTH(commento)-4) BETWEEN 35000 AND 55000;
+-----------------------------------------+
| commento |
+-----------------------------------------+
| This is the first comment 100 200 42500 |
+-----------------------------------------+
The problem is if you have a number not of the same length (e.g. 300 and 131072). Then you need to take a slice large enough for the larger number, and if the number is short, you will get maybe "1 5 300" in your slice. That's where SUBSTRING_INDEX comes to the rescue: by capturing seven characters, from " 131072" to "1 5 300", the ID will always be in the last space separated token of the slice.
IN THIS LAST CASE, when numbers are not of the same length, you will find a problem. The extracted IDs are not numbers at all - to MySQL, they are strings. Which means that they are compared in lexicographic, not numerical, order; and "17534" is considered smaller than "202", just like "Alice" comes before "Bob". To overcome this you need to cast the string as unsigned integer, which further slows down the operations.
WHERE CAST( SUBSTRING(...) AS UNSIGNED) < 4000

Truncate results from SQL to integer value

I have different data values (types), like 10.00 or 2.00. How can I get only its integer value, so I want to get 10 instead of 10.00 and 2 instead of 2.00?
You can use the FLOOR or TRUNCATE function depending on your intention:
SELECT FLOOR(1.999) -- 1
SELECT FLOOR(-1.999) -- -2
SELECT TRUNCATE(1.999, 0) -- 1
SELECT TRUNCATE(-1.999, 0) -- -1
For example, you cound try to do this:
WHERE CONVERT(your_column, SIGNED INTEGER) AS num
FROM
table
ORDER BY
num;
Based on MySQL Documentation CONVERT() and CAST():
CONVERT() provides a way to convert data between different character sets. The syntax is:
CONVERT(expr USING transcoding_name)
In MySQL, transcoding names are the same as the corresponding character set names.
Besides for you also could work ROUND(X), ROUND(X,D):
Rounds the argument X to D decimal places. The rounding algorithm depends on the data type of X. D defaults to 0 if not specified. D can be negative to cause D digits left of the decimal point of the value X to become zero.
mysql> SELECT ROUND(150.000,2), ROUND(150,2);
+------------------+--------------+
| ROUND(150.000,2) | ROUND(150,2) |
+------------------+--------------+
| 150.00 | 150 |
+------------------+--------------+

MySql REGEXP to match two comma separated strings

I have a table containing following values :
id | value |
-----------------------
1 | 1,2,5,8,12,20 |
2 | 11,25,26,28 |
-----------------------
now I want to search some comma separated IDs e.g. '1,3,6,7,11' from above value column e.g.
SELECT id FROM tbl_name
WHERE value REGEXP '*some reg exp goes here containing 1,3,6,7,11*'
LIMIT 1,0;
SELECT id FROM tbl_name
WHERE value REGEXP '*some reg exp goes here containing 3,6,27,15*'
LIMIT 1,0;
above 1st query should return 1 while the 2nd should return NULL
I am new with regular expressions can anyone help. Thanks
REGEXP '(^|,)(1|3|6|7|11)(,|$)'
Will match all values containing one number of the sequence 1,3,6,7,11.
You should not use one column to save several values. Normalize data!
Edited answer

mySQL SELECT IN from string

Here is my table X:
id vals
---------------------
1 4|6|8|
Now table Y:
id name
--------------------
1 a
4 b
6 c
8 d
Now I want the following:
select * from Y where id IN (replace(select vals from X where id = '1'),'|',',')
But this does not seem to work. Any ideas why?
You may use FIND_IN_SET instead of just IN, normal IN keyword couldn't search between comma seperated values within one field.
For example
mysql> select FIND_IN_SET(4, replace('4|6|8|','|',','));
+-------------------------------------------+
| FIND_IN_SET(4, replace('4|6|8|','|',',')) |
+-------------------------------------------+
| 1 |
+-------------------------------------------+
1 row in set (0.00 sec)
Replace gives you a string back - but it's a string value, not a string as in part of your query.
What you can do is instead of using IN, use a REGEXP to match within your original string, for example:
vals REGEXP '[[:<:]]4[[:>:]]'
would be true only if there is a "4" in the original string that isn't part of a larger number (thus if you have 3|44|100 it wouldn't match on "4" but would match on "44").
The [[:<:]] and [[:>:]] are "left side of word" and "right side of word" respectively.
To generate that string, you can do something like...
CONCAT('[[:<:]]', CAST(id AS CHAR), '[[:>:]]')