Guys in a few days I have an exam (midterm), so I am trying to execute every possible test which could be in midterm, suppose that we have employees table where phone number is given in this form abc.edf.ghi (all these are numbers not strings), how could I list these employees who's phone number contains edf? I dont think that we can use substring function because it is number, am I correct? Also I can't execute division by sum number like in c++(division by 100,mod 100 and so on,)so please help me, sorry if my question is too much nonsense. I need just for practice.
Oracle says substr is for string only, but you can use substr for columns that are defined as NUMBER datatype,too.
(Assumed that the format of PHONENUMBERCOLUMN is abc.edf.ghi)
select * from YOURTABLE where substr(PHONENUMBERCOLUMN,5,3)='edf'
NOTE: It should be 'edf', not edf, if the datatype is other than NUMBER. Always use single quotation marks to be on the safe side, whether the datatype of the column is number or string (char,varchar,varchar2 etc.)
Don't make a mistake of thinking that phone number is a number. Phone number is a string which usually consists mainly of digits.
Imagine a phone number beginning with some zeros. If you'd store it as a number they will be truncated while they might be important and might make a difference. Storing it as a string makes it secure.
Additionally, storing it as a string enables you to use SUBSTR and other functions named similarly and doing more or less the same thing, which should solve your problem.
In MySQL you can try the SUBSTRING() function. If the phone number is in the format you show it has to be a varchar not a INT.
For Oracle use substr()
Related
I need to make some changes in SQL within a CURSOR. Previously, the maximum value for column 'code' was 4 characters (e.g. K100, K101,....K999) but now it needs to be 8 characters (e.g. K1000, K1001, K1002,....K1000000).
CURSOR c_code(i_prefix VARCHAR2)
IS
SELECT NVL(MAX(SUBSTR(code,2))+1,100) code
FROM users
WHERE code LIKE i_prefix||'___';
The 'code' column value starts from 100 and increments +1 each time a new record is inserted. Currently, the maximum value is 'K999' and I would like it to be K1000, K1001, K1002 and so on.
I have altered and modified the 'code' column to VARCHAR(8) in the users table.
Note: i_prefix value is always 'K'.
I have tried to amend the SQL -
CURSOR c_code(i_prefix VARCHAR2)
IS
SELECT NVL(MAX(SUBSTR(code,2))+1,100) code
FROM users
WHERE code LIKE i_prefix||'________';
However, it restarts from 100 and not from K1000, K1001, K1002, etc. each time a record is inserted.
I have been suggested to use REGEXP_LIKE() but not sure how to properly use it to get the desired outcome in this case.
Can you please guide me on how can we get this result using REGEXP_LIKE().
Thank you.
Your old code
WHERE code LIKE i_prefix||'___';
will match K followed by exactly three characters, which is what you had. Your new code
WHERE code LIKE i_prefix||'________';
will match K followed by exactly eight characters, which is one too many for a start, since you said the total length was eigh - which means you need sever wilcard placeholders:
WHERE code LIKE i_prefix||'_______';
... but that still won't work at the moment since your existing values aren't that long. As all your current values are at least four, you could do:
WHERE code LIKE i_prefix||'___%';
which will match K followed by three or more characters - with no upper limit, but your column is restricted to eight too anyway.
If you did want to use a regular expression, which are generally slower, you could do:
WHERE REGEXP_LIKE(code, i_prefix||'.{3,7}');
which would match K followed by three to seven characters, or:
WHERE REGEXP_LIKE(code, i_prefix||'\d{3,7}');
which would only match K followed by three to seven digits.
fiddle
However, I would suggest you use a sequence to generate the numeric part, and just prefix that with the K character. The sequence could start from 100 on a new system with no data, or from the current maximum number in an existing system with data.
I would also consider zero-padding the data, including all the existing values, to allow them to be compared; so update K100 to K0000100. Or if you can't do that, once you get past K199 jump to K2000000. Either would then allow the values to be sorted easily as strings. Or, perhaps, add a virtual column that extracts the numeric part as a number.
I have a column of type bigint (ProductSerial) in my table. I need to filter the table by the Product serial using like operator. But I found that, like operator can't be used for integer type.
Is there any other method for this (I don't want to use the = operator).
If you must use LIKE, you can cast your number to char/varchar, and perform the LIKE on the result. This is quite inefficient, but since LIKE has a high potential of killing indexes anyway, it may work in your scenario:
... AND CAST(phone AS VARCHAR(9)) LIKE '%0203'
If you are looking to use LIKE to match the beginning or the end of the number, you could use integer division and modulus operators to extract the digits. For example, if you want all nine-digit numbers starting in 407, search for
phone / 1000000 = 407
Although I'm a bit late to the party, I'd like to add the method I'm using to match the first N given numbers (in the example, 123) in any numeric-type column:
SELECT * FROM MyTable WHERE MyColumn / POWER(10, LEN(MyColumn) - LEN(123)) = 123
The technique is similar to #dasblinkenlight's one, but it works regardless of the number of digits of the target column values. This is a viable workaround if your column contain numbers with different length and you don't want to use the CAST+LIKE method (or a calculated column).
For additional details on that (and other LIKE workarounds) check out this blog post that I wrote on this topic.
If you have control over the database you could add a calculated column to copy the integer value to a string:
ALTER TABLE MyTable
ADD CalcCol AS (CAST(ProductSerial AS VARCHAR)) PERSISTED
And query like:
SELECT *
FROM MyTable
WHERE ProductSerial LIKE '%2548%'
This will move the calculation to the insert/update and only on rows inserted/updated rather then converting every row for each query.
This may be a problem if there are a lot of updated to columns as it will add a very small overhead to these.
There may be a way to do it mathematically using modulus but this would take a lot of working out and testing.
You can change your Field PhoneNumbers and store as String and then use the Like You can alter your table so that you can use the LIKE statement, if you still want to use BIGint for your phone numbers, you cannot get the exact Phone Number without using = the method you can use is Between method that looks for the Numbers that are inside the range.
For the edited question: I think you should use = sign for their ID, or convert the Int to String and then Use Like.
The original question related to a phone number. OP has since edited it to refer to serial numbers. This answer refers to the original question only.
My suggestion is to avoid storing your phone numbers as integers in the first place, and thus the problem does not occur. My phone number is in the form, internationally, of:
+44 7844 51515
Storing it as an integer makes no sense here, as you will never need to do any mathematical operation on it, and you would lose the leading plus. Within the UK, it is:
07844 51515
and thus storing it as an integer would lose its leading zero. Unless you have a very very specific requirement to store it as an integer, you would fare significantly better storing it as a string instead.
[Note: Not actually my phone number]
I'm importing data from one system to another. The former keys off an alphanumeric field whereas the latter requires a numeric integer field. I'd like to find or write a function that I can feed the alphanumeric value to and have it return a number that would be unique to the value passed in.
My first thought was to do a hash, but of course the result of any built in hashes are going to contains letters and plus it's technically possible (however unlikely) that a hash may not be unique.
My first question is whether there is anything built in to sql that I'm overlooking, and short of that I'd like to hear suggestions on the easiest way to implement such a function.
Here is a function which will probably convert from base 10 (integer) to base 36 (alphanumeric) and back again:
https://www.simple-talk.com/sql/t-sql-programming/numeral-systems-and-numbers-conversion-in-sql/
You might find the resultant number is too big to be held in an integer though.
You could concatenate the ascii values of each character of your string and cast the result as a bigint.
If the original data is known to be integers you can use cast:
SELECT CAST(varcharcol AS INT) FROM Table
Does anyone know a good way to count characters in a text (nvarchar) column in Sql Server?
The values there can be text, symbols and/or numbers.
So far I used sum(datalength(column))/2 but this only works for text. (it's a method based on datalength and this can vary from a type to another).
You can find the number of characters using system function LEN.
i.e.
SELECT LEN(Column) FROM TABLE
Use
SELECT length(yourfield) FROM table;
Use the LEN function:
Returns the number of characters of the specified string expression, excluding trailing blanks.
Doesn't SELECT LEN(column_name) work?
text doesn't work with len function.
ntext, text, and image data types will be removed in a future version
of Microsoft SQL Server. Avoid using these data types in new
development work, and plan to modify applications that currently use
them. Use nvarchar(max), varchar(max), and varbinary(max) instead. For
more information, see Using Large-Value Data Types.
Source
I had a similar problem recently, and here's what I did:
SELECT
columnname as 'Original_Value',
LEN(LTRIM(columnname)) as 'Orig_Val_Char_Count',
N'['+columnname+']' as 'UnicodeStr_Value',
LEN(N'['+columnname+']')-2 as 'True_Char_Count'
FROM mytable
The first two columns look at the original value and count the characters (minus leading/trailing spaces).
I needed to compare that with the true count of characters, which is why I used the second LEN function. It sets the column value to a string, forces that string to Unicode, and then counts the characters.
By using the brackets, you ensure that any leading or trailing spaces are also counted as characters; of course, you don't want to count the brackets themselves, so you subtract 2 at the end.
Do you please have any idea which way should I store the IMEI? Should I store it as a bigint? or may be real or float or varchar? IMEI takes 15 characters and normally it is all numbers without any spaces or seperators.
Are you referring to mobile equipment #'s, as described here ? If you're going to search on partial matches of the number, you'll want to store it as some type of character representation. Any type of integer (or bigint) value is going to make things more challenging when it comes to partial-match searching. Also, if you want to verify the check digit, you need to walk through each digit in the IMEI, so again, a character representation is going to work better in this case.