MySQL swap numbers for letters in field - mysql

If I take a value of 12345 from MySQL and I want to display that at the front end as Mo Tu We Th Fr, how can I do that allowing for all possible combinations?
I could write a case statement but there are going to be many hundreds of combinations to cover all possible values.
The value will be anything from 1 to 7 characters long using between digits between 1 and 7 and could be in any order so 3417 should read We Th Mo Su whilst 645 should read Sa Th Fr and so on. I cannot do this in the application so have to try and figure out how to do it in MySQL. These are stored in MySQL as a varchar in a single column.
Can I use replace multiple times in the same select so something like:
REPLACE(REPLACE(REPLACE(field, '1', 'Mo '), '2', 'Tu'), '3', 'We')
or is there another way?

You can create a helper table that contains 2 columns :
1, su
2, mo
3, ...
then just join the day number to get the second column of the helper table.
If all you want to do is display this in a fronend, you can have a "dictionary" to translate the values.

Lets say for example you have a Table in the structure
tl_days
__________
id | alias
And we have some data such as
id: 1, alias : Mon
id: 2, alias : Tue
We can run a simple query to check the id against an array of numbers.
SELECT alias FROM 'tl_days' WHERE id in (1,2,3,4);
Will return the days as your abbreviations.

You should not write replace for all the values if there are multiple of them, Instead create a mapping table 1|su,2|mo ..., Then use join to fetch the 'su','mo' values from the mapping table

First you would need to ensure that the table schema data matches. If changing from numeric value to text value is acceptable.
Update table_name set column_name =
(
CASE
when column_name = 1 then 'Mo'
when column_name = 2 then 'Tu'
when column_name = 3 then 'We'
when column_name = 4 then 'Th'
when column_name = 5 then 'Fr'
End
);
Here is an SQL FIDDLE displaying such a change.

Related

Compairing two strings in MYSQL

I have a sequence of 20 numbers from 0 to 2, I want to compare this string with other sequences saved in my database, the problem is that the lenght of the strings saved on the database fluctuates.Also the comparison needs to be done from the end to the start.
Example of what I want:
20 digits string:
'1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1'
couple of strings saved in the database:
1 - '1,1,2,1'
2 - '2,1,2,2,2,2'
3 - '2,1'
4 - '1,1,2,1,2,1'
In this case the query would return the 1 and 3 only
create table mytable ( s varchar(60) );
insert into mytable values
('1,1,2,1'),
('2,1,2,2,2,2'),
('2,1'),
('1,1,2,1,2,1');
set #x = '1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1';
select s from mytable
where right(#x, length(s)) = s;
Output:
s
1,1,2,1
2,1
Fiddle: https://www.db-fiddle.com/f/r5m2hPbnmUu5VQfYvMVtir/0
You could use a LIKE trick here. For example, to check for the first string 1,1,2,1:
SELECT *
FROM yourTable
WHERE ',1,1,2,1,2,1,0,1,2,1,2,1,0,1,2,1,1,1,2,1,' LIKE '%,1,1,2,1,%';

Return strings which contains number on specific position

I am basic on SQL queries and I need some help.
I have to select all string values which contains number e.g. 7 only on specific position in that string.
For example:
I have string: 987654321 and if on position 3 I will have number 7, then it should be selected.
So in example this string will be selected, because on 3rd position I have number 7.
Is there any SQL function for that, or something which could help me?
EDIT:
Example table
TABLE
Numbers Value
987654321 1
123456789 2
789009871 3
654321092 4
847949372 5
Output:
TABLE
Numbers Value
987654321 1
847949372 5
Statement:
SELECT table.numbers
FROM TABLE
WHERE substr(table.numbers,3,1)='7' <--- what to do here? --->
Many thanks in advance.
For a regex option, you may use MySQL's REGEXP operator:
SELECT *
FROM yourTable
WHERE num REGEXP '^[0-9]{2}7';
On Oracle, you could use REGEXP_LIKE:
SELECT *
FROM yourTable
WHERE REGEXP_LIKE(num, '^[0-9]{2}7');
You should use case statement.
select case when substr(stringcol, 3,1) = '7' then stringcol else "not valid" end as stringcol from <Table Name>

I need to display the data, if at least one string present in another column using SQL

I have two columns in a table, column 1 contains tom jerry and column 2 has tom xxxx . I need to fetch the row at least one string is present the other column data
column1 column2
-----------------------------
tom jerry : tom xxx
tiger : tom yyy
tiger lion : lipard
lion tom : tiger lion
23 : 235 452
23 : 23
Expected result:
column1 column2
---------------------------
tom jerry : tom xxx
lion tom : tiger lion
23 : 23
Here is my approach:
Put both columns to another table with identity column (to identify each row)
Write a function to split text by a string (in this case pass a space)
Here you can use built in function if it is higher than SQL Server 2016
Get the identity and the splitted data to 2 tables each for column 1 and 2
Join the 2 tables for matches in Col-Split data, and get the IDs
Now Query for the data in table in above 1
Here is the Fiddle assuming that the code is for SQL Server 2016
In MySQL, you can use a regular expression for the data you have presented:
where column1 regexp replace(column2, ' ', '|') or
column2 regexp replace(column1, ' ', '|')
This may or may not work as stated. For instance, this will match "lion" and "lions" -- that meets what you are describing as I read it. That said, you can modify the patterns to enforce word breaks if you have something slightly different in mind.
You'd be able to achieve this by creating a function wherein you will pass value of column1 and column2. The function will do the heavy-lifting of checking if column1 value (multiple words separated by whitespace) has any of its word matching in column2 value. The pseudo code of function should be something like this -
Function bool IsCol1WordPresentInCol2(varchar2 col1value, varchar2 col2value)
Step 1: Split col1value based on whitespace to get series of words
Step 2: Split col2value based on whitespace to get series of words
Step 3: Outer loop to iterate through all words of col1 (extracted from step 1)
Step 4: Inner loop to iterate through all words of col2 (extracted from step 2)
Step 5: Check if the col1 and col2 words do match. At any point, if any match is found, return true from the function; else false.
Step 6: Based on the returned bool value from this function, you'd be able to identify, in your calling logic, if that record satisfies your condition.
You can use instring function to achieve this. Function depends on the database you use. Below is the query,
select * from table1 where col1 > col2;
select distinct t1.* from table1 t1
inner join table1 t2
on (instr(substring(t1.col1, instr(t1.col1, ' ') -1), col2) > 0);

How to properly format overlapping mySQL IN and NOT IN conditions

I have the following mySQL table:
data
1
2
3
4
5
6
7
8
9
I would like to supply my select statement with two seperate lists
Exculde List:
1,4,5,7
Include List:
1,2,3,4,5,6,7
I tried the following statement:
Select * FROM table WHERE data NOT IN ('1,4,5,7') AND data IN ('1,2,3,4,5,6,7)
Expecting the following output:
data
2
3
6
But I received no results. I realize I passed an impossible condition but I don't know how to format my query to return the expected results.
Can anyone tell me what I'm doing wrong here?
IN takes a list of values, not a string that holds a delimited list of values.
Examples:
x IN (1, 2, 3)
x IN ('a', 'b', 'c')
Use IN (1,2,3) and not IN ('1,2,3') as the former compares to individual values 1, 2 and 3 while the latter is against the literal string 1,2,3.
Select * FROM ( (Select * FROM table WHERE data NOT IN ('1,4,5,7') ) AS table WHERE data IN ('1,2,3,4,5,6,7)
you try againt

How to pickup date from long string Name column in oracle

I have table with column 'ID', 'File_Name'
Table
ID File_Name
123 ROSE1234_LLDAtIInstance_03012014_04292014_190038.zip
456 ROSE1234_LLDAtIInstance_08012014_04292014_190038.zip
All I need is to pickup the first date given in file name.
Required:
ID Date
123 03012014
456 08012014
Here's one method assuming 8 characters after 2nd _ is always true.
It finds the position of the first _ then looks for the position of the 2nd _ using the position of the first _+1 then it looks for the 8 characters after the 2nd _
SELECT Id
, substr(File_name, instr(File_name,'_',instr(File_name,'_')+1)+1,8) as Date
FROM Table
or
a more elegant way would be to use a RegExp_Instr Function which eliminates the need for nesting instr.
SELECT Id, substr(File_name,REGEXP_INSTR(FileName,'_',1,2)+1,8) as date
FROM dual;
Why don't you simply put the date in separate column? E.g. you can than query the (indexed) date. The theory says the date is a property of the file. It's about avoiding errors, maintainability and so on. What in the zip files? Excel sheets I suppose :-)
Use a much simplified call to REGEXP_SUBSTR( ):
SQL> with tbl(ID, File_name) as (
2 select 123, 'ROSE1234_LLDAtIInstance_03012014_04292014_190038.zip' from dual
3 union
4 select 456, 'ROSE1234_LLDAtIInstance_08012014_04292014_190038.zip' from dual
5 )
6 select ID,
7 REGEXP_SUBSTR(File_name, '_(\d{8})_', 1, 1, NULL, 1) "Date"
8 from tbl;
ID Date
---------- ----------------------------------------------------
123 03012014
456 08012014
SQL>
For 11g, click here for the parameters to REGEXP_SUBSTR( ).
EDIT: Making this a virtual column would be another way to handle it. Thanks to Epicurist's post for the idea. The virtual column will contain a date value holding the filename date once the ID and filename are committed. Add it like this:
alter table X_TEST add (filedate date generated always as (TO_DATE(REGEXP_SUBSTR(Filename, '_(\d{8})_', 1, 1, NULL, 1), 'MMDDYYYY')) virtual);
So now just insert the ID and Filename, commit and there's your filedate. Note that its read-only.