SQL get numbers that contain certain digits - sql

How do I get number field that contain 878 as reflected in the result. It should contain two 8 and one 7.
Edit : using TSQL
Number
878
780
788
700
Result
878
788

There are only 3 combinations so what about the crudest of them all?
Number = 788 OR Number = 878 OR Number = 887
Or even:
Number IN (788,878,887)
If numbers are not just 3 digits then cast the number as string and then:
NumberAsString LIKE '%887%' OR NumberAsString LIKE '%878%' OR NumberAsString LIKE '%788%'

A three digit number consisting of exactly one seven and two eights:
where number in (788, 878, 887)
Everything else would be overkill for this simple task.
If the task were different, say, the number can have more digits and must contain exactly one seven and two eights, then we could use an appropriate combination of LIKE and NOT LIKE to get what we are looking for. E.g:
where number like '%7%' -- contains a 7
and number like '%8%8%' -- contains two 8s
and number not like '%7%7%' -- doesn't contain more than one 7
and number not like '%8%8%8%' -- doesn't contain more than two 8s

UPDATE:
This is not a good solution, in stead I would go for the next solution suggested here.
If you are using MySQL REGEX is your friend:
SELECT * FROM _TABLE_
WHERE `Number` REGEXP "[7]{1}" AND `Number` REGEXP "[8]{2}";
More info: https://dev.mysql.com/doc/refman/8.0/en/regexp.html
I think in SQL Server should be something like this:
SELECT * FROM _TABLE_
WHERE `Number` LIKE '%[7]{1}%' AND `Number` LIKE '%[2]{1}%';
More info: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/like-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15

Related

How to regex match multiple items

I have a reviews table as follows:
r_id
comment
1
Weight cannot exceed 40 kg
2
You must not make the weight go over 31 k.g
3
Don't excel above 94kg
4
Optimal weight is 45 kg
5
Don't excel above 62 kg
6
Weight cannot exceed 7000g
What I want to select is the weight a r_id's cannot exceed. So my desired output is
r_id
max weight
1
40
2
31
3
94
5
62
As you can see, r_id 4 wasn't included since it wasn't taking about the maximum weight and 6 wasn't included because it is in grams. I am struggling with two things.
There are multiple phrases, how can I do a OR operator check in my regex column.
Sometimes the kg number is written like 40kg, 40 KG, 40 k.g or 40kilos. While all things are kilograms, the kg is written in different ways. How can I only extract the number (but ensuring the kg is written in one of the above ways, so I don't accidentally extract something like 4000g.
SELECT
r_id,
REGEX_SUBSTR(REGEX_SUBSTR('cannot exceed [0-9]+ kg'), '[0-9]+ kg')) as "max weight"
FROM reviews;
My statement only checks for one particular type of sentence and doesn't check if the number is in kilograms.
You could just extract the number from the string. There only appears to be one and then check if the string looks like certain patterns:
select regexp_substr(comm, '[0-9]+')
from reviews
where regexp_like(comm, '(exceed|go over|above).*[0-9]+ ?(kg|k.g)');
Here is a db<>fiddle.
You can use a more robust regex expression to extract the number.
I don't have an oracle DB, but try something like:
SELECT
r_id,
REGEX_SUBSTR(comment, '([0-9]+) ?(k\.?g\.?|kilos)', 1, 1, 'i') as "max weight"
FROM reviews;
You can see this regex matching the given string in action at https://regex101.com/r/07Rstk/1. This also explains what the regex means.
We also turn on the case insensitive flag in order to properly handle any capitalization. https://docs.oracle.com/cd/E18283_01/olap.112/e17122/dml_functions_2069.htm
Edit: To do checks for exceed, go over, etc. Note that we have changed the position parameter from 1 to 2 since we now care about the second capture group.
SELECT
r_id,
REGEX_SUBSTR(comment, '(exceed|go over|above)\h*([0-9]+) ?(k\.?g\.?|kilos)', 1, 2, 'i') as "max weight"
FROM reviews;

How do you do multiple substrings for a field in Teradata?

I have a field to pull account numbers which have different lengths and I want to pass the last four digits of the account number. The dilemma I am having is that since they are different lengths I am having trouble in substringing the fields. The standard length is 11 digits but there are accounts with 9 digits and 7 digits.
How do I substring those values in multiple substrings to capture all the account last 4 digits in one query?
This currently what I have:
SELECT SUBSTRING(ACCT_NBR,7,4) AS BNK_ACCT_NBR
FROM NAMEOFTABLE;
I want to have additional substrings to capture the account numbers that don't have 11 digits similar to
SUBSTRING(ACCT_NBR,5,4)
SUBSTRING(ACCT_NBR,4,4)
The results should look like:
76587990891 - 0891
654378908 - 8908
45643456 - 3456
Can you please help me in figuring out how I can do that?
Thanks.
Is ACCT_NBR a VarChar or an INT?
VarChar:
Right (ACCT_NBR,4)
Substr(ACCT_NBR,Char_Length(x)-3)
INT:
ACCT_NBR MOD 10000

T - SQL statement for number ranges

Create table temp
(
ID nvarchar(50)
)
ID contains numeric values prevailing zeros in some cases so it is defined as varchar
How to get values starts with 3555 to 3999 and 8000 to 9999.There is no specific rule that length is always 4.
Eg:
3555
35688888888888
3590909
8000
85805667
all of the values are valid and are to be fetched.
Please let me know T- SQL statement for the above scenario
You can use few expressions with LIKE. If you have an index on ID, it would use it, so it will be efficient. Something like this:
SELECT
ID
FROM
temp
WHERE
ID LIKE '3[5-9]%'
OR ID LIKE '[89]%'
LIKE '3[5-9]%' matches any string that starts with 3 and which second character is 5 or 6 or 7 or 8 or 9. After these two characters there can be 0 or more other characters. Any number of extra characters.
LIKE '[89]%' matches any string that starts with 8 or 9 and any number characters after.
You can extract the first four chars, convert that to a number and query like this:
SELECT
[ID]
FROM temp
WHERE convert(int,LEFT([ID],4)) BETWEEN 3500 AND 3999
OR convert(int,LEFT([ID],4)) BETWEEN 8000 AND 9999
For lots of data this will be horribly slow, so if you need performance I would recommend to add an indexed int column to the table where you store the number that represents the first four digits of ID.

Select statement with offset in like

I have an entry "123456789" in my table.
Select * from map where col like '%1%5%6%7%9'.
I want to retrieve the records where the order of the input sequence matches, but i also want to ensure that the distance between any 2 matching digits is less than 2.
Is there any way i can specify an offset ?
The input is 189, and it selects the record, but i want 1.8.9 to be within 2 of each other. 12879 would be an acceptable output but 123456789 would not be.
Below statement requires 3 to 5 characters between 1 and 5:
SELECT * FROM map WHERE col LIKE '%1___%5%6%7%9' AND col NOT LIKE '%1______%5%6%7%9%'
Using _s you may force any count of characters.
EDIT: Character corrected. Source: SQLite expression
Check in this SQL Fiddle sample.

Using a query in Microsoft Access to compare two fields and find multiple matching values

I have a problem I am trying to solve using a query instead of VBA.
I have two fields which we'll call "FPC" and "Code". Both fields contain numbers. An FPC value will match a Code value. What I want to make sure is that once an FPC value matches a Code value, the same FPC value does not match up with a DIFFERENT Code Value and vice versa - Once a Code Value is used, I don't want the Code Value to match up with more than one FPC.
It is important to note that there are duplicate values used in both fields.
Here is an example:
FPC CODE
1 12
1 12
1 14
2 16
3 11
3 11
4 17
5 19
6 16
There are two errors here:
1. The FPC "1" is matched up with two different Code Values.
2. The Code "16" is matched up with two different FPC values.
Please let me know your suggestions. I was thinking a query would help, and then running VBA to pull the results (there is tens of thousands of records).
What is the purpose of the query? Just to identify problems? If yes then something like
select FPC, count(distinct(CODE)) from tableName where count(distinct(CODE)) >1 group by FPC
(and the converse query for CODE vs. FPC) should be OK.