query a telephone number mysql lots of formats - mysql

I'm trying to do a search where the last 5 digits of a number match out of 12
For example
text column "tel" contains "44 20 01122 4455" There maybe spaces there may not be spaces. It may not have a country code at the front, it may have a "0" and it could be a variable length from 13 digits to just 4 digits.
I would like to be able to match the following numbers and return the record.
44 20 01122 4455 (last 13 digits with spaces)
4420011224455 (last 13 digits no spaces)
020 01122 4455 (last 10 digits with spaces)
020011224455 (last 10 digits no spaces)
011224455 (last 9 digits)
224455 (last 6 digits)
24455 (last 5 digits)
4455 (last 4 digits)
The most common problem I will need to find is numbers stored as:
44 20 01122 4455 (last 13 digits with spaces)
4420011224455 (last 13 digits no spaces)
020 01122 4455 (last 10 digits with spaces)
020011224455 (last 10 digits no spaces)
but I only get 4455 or 24455 to search with
What mysql search query commands can I use?

You mean this:
SELECT TRIM(LEADING ' ' FROM RIGHT(LPAD(REPLACE(tel, ' ', ''), 13, ' '), 13))
This should replace all spaces with blanks. Then it will pad the string with spaces till its 13 characters long (in case its only 4 characters). Then it will trim the leading spaces it padded.

Would this work?
SELECT tel
FROM yourTable
WHERE RIGHT( REPLACE ( tel, ' ', ''), 5) = #param
The REPLACE() function removes any spaces. The RIGHT() function gets the last five characters.

Related

MySQL extract first 4 digits

I want to run a query in mysql which will return the record where the first 4 digits are '0123' or '0798' from the following column:
Number
0123 427 6465
0123 1451
01 23 46 47
0123 945675
07984 473456
0845 46 47
(012377) 5258
0800 586931
012 3668 6098
0 1238592371
I want the query to return all records where '0123' or '0798' are the first 4 numeric characters regardless of if there are other characters before or in between. E.g. I would want record 7 returned even though '0123' is in brackets. And I would want record 10 returned even though it is written as '0 123' i.e. there is a space in between.
Is regex relevant here? If so, what would the regex expression be?
Use a combination of LEFT and REPLACE.
REPLACE will strip out any unwanted brackets and whitespaces, and LEFT will select the first four characters, starting from left, of the newly formatted value which will be used in the WHERE clause selecting for values IN '0123', '0798'.
SELECT `number` FROM Numbers WHERE LEFT(REPLACE(REPLACE(REPLACE(`number`, '(', ''), ')', ''), ' ', ''), 4) IN ('0123', '0798')
Fiddle.
Result:
Number
0123 427 6465
0123 1451
01 23 46 47
0123 945675
07984 473456
(012377) 5258
012 3668 6098
0 1238592371
Also, it's worth noting, number is a Reserved Word in MySQL. I used backticks ` to escape it, however, it is advised that you do not use reserved words in your naming conventions.
We can use REGEXP_REPLACE function to remove all others characters other than number and get first four using the below query,
SELECT LEFT(REGEXP_REPLACE(Number, '[^0-9]+', ''), 4) as 4digitonly FROM Numbers a;
Please refer How to get only Digits from String in mysql?
Nothing is better than regex, yes they make us think even think recursivelly :)
Here is the query(of course it can be refactored N times):
SELECT n.number FROM Numbers n WHERE n.number REGEXP '^.*(0[ \t\r\n]*1[ \t\r\n]*2[ \t\r\n]*3).*|^.*(0[ \t\r\n]*7[ \t\r\n]*9[ \t\r\n]*8).*$'
Fiddle

How is "byte" datatype size = 1 byte while it can have 3 digit numbers?

Data Type: Byte
Size: 1 byte/ 8 bits
Info: An integer between -128 and 127
I found this online, but I was a bit confused, I am new to binary things, sorry if I am wrong, but one single digit is 8 bits, right? So, if that datatype has 3 digits of number, how is its size = 1 byte/ 8bits??
I tried checking in https://www.rapidtables.com which converts text to binary numbers, I put "127" as input and it gave me the output as
00110001 00110010 00110111
which is 24 bits/ 3 bytes..
which makes sense in my brain...
So what does that above information mean by that?
I think you confuse a string number with an integer.
A single byte (8-bits) can represent 256 numbers in the following ranges:
signed: -128 - 127, max: 2 ^ 8 / 2 - 1 (2 ^ 7 - 1)
unsigned: 0 - 255, max: 2 ^ 8 - 1
The website from your link converts a text to binary so you have 3 ASCII characters:
char
dec
hex
bin
'1'
49
0x31
0b110001
'2'
50
0x32
0b110010
'3'
51
0x33
0b110011
References:
Signed number representations

SQL Order By but invert for one element

I've got an SQL query which results upto the following
Code int1 int2 int3 S
C12 21 22 14 1
C33 43 56 2 3
C34 23 2 1 3
C55 33 92 12 5
CB56 45 66 10 5
MA10 10 11 12 1
This is the result of using OrderBy on Code
However I do not want it to order according to alphabets
But by the number after it for ex 1 in M1 and 33 in C33
In some cases the number after the alphabet may be 3 digits like E344
What I want it to look like
Code int1 int2 int3 S
MA10 10 11 12 1
C12 21 22 14 1
C323 43 56 2 3
C325 43 56 2 3
C34 23 2 1 3
C525 33 92 12 5
CB56 45 66 10 5
What I need is
M Should always show on top if Present
Then Sort According to Number on first place
Then Sort it according to the number on the Second place
Then sort it according to the number on the third place
The field 's' will always consist of the first digit from the Code
step 1 split up the column into 2 columns, 1 containing the letters, the other containing the numbers:
SELECT
substring(code,0,PATINDEX('%[0-9]%', Code)) as letters,
substring(code,PATINDEX('%[0-9]%', Code)) as numbers,
fields
FROM table
step 2 Convert the numbers to integer and sort
CONVERT(substring(code,PATINDEX('%[0-9]%', Code)),UNSIGNED INTEGER) as numbers
step 3 sort
Order by field1 asc, field2 desc... etc
It might be easier to use a subquery:
select * from
(SELECT
substring(code,0,PATINDEX('%[0-9]%', Code)) as letters,
CONVERT(substring(code,PATINDEX('%[0-9]%', Code)),UNSIGNED INTEGER) as numbers,
fields
FROM table) T
order by numbers asc, letters desc
This is conceptually simple: you want to order first by whether the code starts or not with the letter 'M', and then by the numeric portion of the code. You say in a comment:
extracting the first digit then order and then extracting the second
digit and then order and then extracting the third digit and then
order
This is exactly how alphabetical order has always worked. You order by first character; when it is the same you order by the second character, etc. so you need no special treatment for that case. Just get the numeric part of the code as a string, then order by it.
At this point, the only problem left to resolve is how to extract the numeric part of the code. That would be easy with PATINDEX() (as Alfons pointed out) but unfortunately MySQL does not support PATINDEX() as far as I know.
Now, what follows is extremely ugly, but it does work. Basically we get the non-numeric part of the string by removing all the numeric characters from it, then use the length of the non-numeric part to extract the numeric part.
SELECT mytable.* FROM mytable
INNER JOIN (
SELECT
code,
RIGHT(code, LENGTH(letters)) numbers
FROM (
SELECT
code,
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
code, 0, ''), 1, ''), 2, ''), 3, ''), 4, '')
, 5, ''), 6, ''), 7, ''), 8, ''), 9, '') letters
FROM mytable
) letters_table
) numbers_table
ON numbers_table.code = mytable.code
ORDER BY (numbers_table.code like 'M%') DESC,
numbers_table.numbers ASC
This solution is probably inefficient. However, I don't think you can get any acceptable efficiency anyway unless you store the numeric part on a separate column that you can index.
As you are guaranteeing that s is the value of the first digit in the code, this can be used to find the start of the code and from there, get the numeric part of the code. As you want to have all the codes starting with 'M' first, this results in the following ORDER BY clause:
... ORDER BY IF(SUBSTR(code, 1, 1) = 'M', 0, 1), SUBSTR(code, LOCATE(s, code))

Binary digits in decimal

How do you represent (decimal) integer 50 in binary?
How many bits must be "flipped" in order to capitalize a lowercase 'a' that is represented in ASC11?
How do you represent the (decimal) integer 50 in, oh, "hexadecimal," otherwise known as base-16? Recall that decimal is simply base-10, and binary is simply base-2. Infer from those base systems how to represent this one?
Please answer these questions for me.HELP.
To help you some:
Binary is only made up of 1's and 0's.This may help you understand binary conversion
Decimal is 0-9
Hexadecimal is 0-9, then A-F (so A would represent 10, B would be 11, etc up to F which is 15)
Converting from decimal to another base
Here some tips for you regarding conversion to binary:
What is 50 mod 2? What about 25 mod 2 and then 12 mod 2? What are your results if you continue this?
What does any number mod 2 (always) return as result? - 1 or 0
Do you realise any patterns? - You get the reversed binary number as result
Test case 50:
50 mod 2 = 0 - 6th digit
25 mod 2 = 1 - 5th digit
12 mod 2 = 0 - 4th digit
6 mod 2 = 0 - 3rd digit
3 mod 2 = 1 - 2nd digit
1 mod 2 = 1 - 1st digit
The remainders of the divisions concatenated and reverses are: 110010, which is 50 in binary.
Can this be also transformed to further bases? - Yes, as we see with trying to convert 50 to hexadecimal:
50 mod 16 = 2 - 2nd digit
3 mod 16 = 3 - 1st digit
The remainders again concatenated and reversed are 32, which conveniently is 50 in hexadecimal.
In general we can say to convert a number to an arbitrary base you must take the remainder of the number and the base and then divide the number by the base and do the same thing again. In a program this would look something like:
while the number is greater 0 do:
result = (number mod base) + result;
number = number div base;
Converting from any base to decimal
How do you convert a number from an arbitrary base into base 10? First let us do a test case with binary. Lets take the 50 from the previous example: 110010
The method to convert from binary is multiplying every digit with the base to the power of the position of it in the number and adding up the result. The enumeration of the positions begins with 0 at the least significant digit. Our previous number would then look something like this:
1 *2^5 + 1 *2^4 + 0 *2^3 + 0 *2^2 + 1 *2^1 + 0 *2^0
What simplifies to:
32 + 16 + 2 = 50
It also works with any other base, like our 32 from the previous example:
3 *16^1 + 2*16^0 = 48 + 2 = 50
In program this would look something like this:
from end of number to beginning do:
result = result + digit * (base ^ position)

The binary equivalent of the decimal number 104

Ok,so I know that the binary equivalent of 104 is 1101000.
10=1010
4=0100
so , 104=1101000 (how to get this??how these both mix together and get this binary?)
And from the example here...
the octets from "hellohello" are E8 32 9B FD 46 97 D9 EC 37.
This bit is inserted to the left which yields 1 + 1101000 = 11101000 ("E8").
I still understand this part , but how to convert 11101000 to E8?
I'm so sorry for all these noob questions , I just learn it yesterday , I googled and search for a whole day but still not really understand the concept...
Thank you.
Ok,so I know that the binary equivalent of 104 is 1101000.
10=1010
4=0100
You can't break apart a number like 104 into 10 and 4 when changing bases. You need to look at the number 104 in its entirety. Start with a table of bit positions and their decimal equivalents:
1 1
2 10
4 100
8 1000
16 10000
32 100000
64 1000000
128 10000000
Look up the largest decimal number that is still smaller than your input number: 104 -- it is 64. Write that down:
1000000
Subtract 64 from 104: 104-64=40. Repeat the table lookup with 40 (32 in this case), and write down the corresponding bit pattern below the first one -- aligning the lowest-bit on the furthest right:
1000000
100000
Repeat with 40-32=8:
1000000
100000
1000
Since there's nothing left over after the 8, you're finished here. Sum those three numbers:
1101000
That's the binary representation of 104.
To convert 1101000 into hexadecimal we can use a little trick, very similar to your attempt to use 10 and 4, to build the hex version from the binary version without much work -- look at groups of four bits at a time. This trick works because four bits of base 2 representation completely represent the range of options of base 16 representations:
Bin Dec Hex
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F
The first group of four bits, (insert enough leading 0 to pad it to four
bits) 0110 is 6 decimal, 6 hex; the second group of four bits, 1000 is
8 decimal, 8 hexadecimal, so 0x68 is the hex representation of 104.
I think you are making some confusions:
104 decimal is 1101000 which is not formed by two groups splitting 104 into 10 and 4.
The exception is for hex numbers that can be formed by two groups 4 binary numbers (2^4 = 16).
So 111010000 = E8 translates into 1110 = E and 8 = 10000. 1110 (binary) would be 14 (decimal) and equivalent of E (hex).
Hex numbers go from 0 to 15 (decimal) where:
10 (decimal) = A (hex)
11(decimal) = B(hex)
...
15(decimal) = F(hex)
What you're missing here is the general formula for digital numbers.
104 = 1*10^2 + 0*10^1 + 4*10^0
Similarly,
0100b = 0*2^3 + 1*2^2 + 0*2^1 + 0*0^0
And for a hexidecimal number, the letters A-F stand for the numbers 10-15. So,
E8 = 14*16^1 + 8*16^0
As you go from right to left, each digit represents the coefficient of the next higher power of the base (also called the radix).
In programming, if you have an integer value (in the internal format of the computer, probably binary, but it isn't relevant), you can extract the right most digit with the modulus operation.
x = 104
x % 10 #yields 4, the "ones" place
And then you can get "all but" the rightmost digit with integer division (integer division discards the remainder which we no longer need).
x = x / 10 #yields 10
x % 10 #now yields 0, the "tens" place
x = x / 10 #yields 1
x % 10 #now yields 1, the "hundreds" place
So if you do modulus and integer division in a loop (stopping when x == 0), you can output a number in any base.
This is basic arithmetic. See binary numeral system & radix wikipedia entries.