SQL - contains only combinations of specific numbers - sql

There is a Table (let T) with column (let C) containing only numbers. I wish to retrieve the numbers using select that are only a combination of e.g 1,2,3 like 123123, 111111, 112113, 231213 etc. Please help.

Something that only uses standard SQL and which will work in all RDBMSs:
select c from t
where replace(replace(replace(c, '1', ''), '2', ''), '3', '') = ''
and length(c) > 0
For those that support regex, like Postgres:
select c from t
where c rlike '^[123]+$'
Oracle:
select c from t
where regexp_like(c,'^[123]+$');

Just to point out that a standard SQL solution may not work properly in Oracle.
With a table like this:
create table t(c) as (
select '1233' from dual union all
select '1XX3' from dual union all
select 'XX' from dual union all
select '' from dual
)
The standard approach gives:
SQL> select c from t
2 where replace(replace(replace(c, '1', ''), '2', ''), '3', '') = ''
3 and c <> '';
no rows selected
the reason is in the way Oracle handles empty strings :
SQL> select c,
2 case when replace(replace(replace(c, '1', ''), '2', ''), '3', '') = '' and c <> '' then 'MATCH'
3 else 'NO MATCH'
4 end as checkMatch
5 from t;
C CHECKMAT
---- --------
1233 NO MATCH
1XX3 NO MATCH
XX NO MATCH
NO MATCH
In a simple example:
SQL> select case when '' = '' then 'true' else 'false' end
2 from dual;
CASEW
-----
false
In Oracle, the check should be against NULL:
SQL> select c,
2 case when replace(replace(replace(c, '1', ''), '2', ''), '3', '') is null and c is not null then 'MATCH'
3 else 'NO MATCH'
4 end as checkMatch
5 from t;
C CHECKMAT
---- --------
1233 MATCH
1XX3 NO MATCH
XX NO MATCH
NO MATCH
So an Oracle solution without regexp could be:
SQL> select c from t
2 where replace(replace(replace(c, '1', ''), '2', ''), '3', '') is null
3 and c is not null;
C
----
1233

Related

How to change the column value conditionally

I would like to change the column values based on below condition. Appreciate your expert advice on this. I need to prefix the respective column value 'F~' if the column is found in col_lst. Can I achieve this through sql query?
Current Output:
row_id|col_lst|col1|col2|col3|col4
1|col1,col2|1|2|3|4
2|col3,col4|A|B|C|D
3|col2|X|Y|Z|P
Expected Output:
row_id|col_lst|col1|col2|col3|col4
1|col1,col2|F~1|F~2|3|4
2|col3,col4|A|B|F~C|F~D
3|col2|X|F~Y|Z|P
Regards
Mithil
You can use the INSTR function on each column name to determine if it is in the col_lst column.
with test_data(row_id,col_lst,col1,col2,col3,col4) as
( select 1, 'col1,col2', '1', '2', '3', '4' from dual union all
select 2, 'col3,col4', 'A', 'B', 'C', 'D' from dual union all
select 3, 'col2', 'X', 'Y', 'Z', 'P' from dual
)
select row_id
, col_lst
, case when instr(col_lst,'col1')>0 then 'F~' || nvl(col1,' ') else col1 end col1
, case when instr(col_lst,'col2')>0 then 'F~' || nvl(col2,' ') else col2 end col2
, case when instr(col_lst,'col3')>0 then 'F~' || nvl(col3,' ') else col3 end col3
, case when instr(col_lst,'col4')>0 then 'F~' || nvl(col4,' ') else col4 end col4
from test_data;
However this is a case where you should just tell the other team NO. There is nothing added that they cannot determine from the col_lst themselves, and it serves no purpose except output formatting - which the presentation layer should be doing.

Need to replace alpha numeric characters by space and create new column

I need to convert the following
Column 1 Column 2
ABC, Company ABC Company
TA. Comp TA Comp
How can I get Column2 in sql where I am removing all ',' '.' to space.
How about:
with testdata as (
select 'ABC, Company Inc.' as col1 from dual
union all
select 'TA. Comp' as col1 from dual
)
select trim(regexp_replace(regexp_replace(col1, '[[:punct:]]',' '), ' {2,}', ' ')) as col2
from testdata;
Output:
ABC Company Inc
TA Comp
Assuming punctuation is what you're trying to blank out.
You can try to use:
SELECT REGEXP_REPLACE(column1, '[^a-zA-Z0-9 ]+', '')
FROM DUAL
with t (val) as
(
select 'ABC,. Cmpany' from dual union all
select 'A, VC' from dual union all
select 'A,, BC...com' from dual
)
select
val,
replace(replace(val, ',', ''), '.', '') x , -- one way
regexp_replace(val, '[,.]', '') y -- another way
from t
;
VAL X Y
--------------- ---------- ----------
ABC,. Cmpany ABC Cmpany ABC Cmpany
A, VC A VC A VC
A,, BC...com A BCcom A BCcom

sql query to sum data based on criteria

I have my table data sums as follows
---------------------
Building | Area m2
---------------------
|Dante 12 | 10
|Dante 10 | 5
|Dante 9 | 2
|Crandley | 20
|Bence | 30
I want to sum Building Area but buildings like '%dante%' I want to combine into sum "Dante" like below:
-------------------
Building | Area m2
-------------------
Dante | 17
Crandley | 20
Bence | 30
Group by with case will do the trick for sample data given,like of this type can use index as well
Select
case when building like 'dante%' then 'Dante' else building end,
sum([area m2])
from
table
group by
case when building like 'dante%' then 'Dante' else building end
if there are numbers for other columns,you can strip out the numbers first and do the rest of stuff like below
;with cte
as
(select REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE (building, '0', ''),
'1', ''),
'2', ''),
'3', ''),
'4', ''),
'5', ''),
'6', ''),
'7', ''),
'8', ''),
'9', '') as bulding,aream2
from #temp
)
select building,sum(aream2)
from
cte
group by
building
References:
Remove numbers found in string column
Works only if numeric value is to be removed
Numeric value is to be replaced (Nested replace function can go upto 32 level deep) and group by column.
SELECT x.Building, SUM(x.AreaM2) AS [Area m2]
FROM (
SELECT
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE (Building, '0', '')
,'1', '')
,'2', '')
,'3', '')
,'4', '')
,'5', '')
,'6', '')
,'7', '')
,'8', '')
,'9', '') [Building], AreaM2 FROM Buildings) AS x
GROUP BY x.Building

CONCATENATE a CASE in Oracle SQL

I need to run a CASE expression on a number of columns, the columns are Boolean, so if it's 0 I need to populate the column with the column name and if it's 1, I ignore the column/value. I then need to concatenate all these columns into one. Is it possible to do this in Oracle SQL?
I've tried this:
Select
||CASE
WHEN COL_A = 0 THEN 'COL_A'
ELSE ''
END||','
||CASE
WHEN COL_B = 0 THEN 'COL_B'
ELSE ''
END||
from ABC.123
Can this even been done? If not this way are there any other ways?
Yes, it will work (if you clean up the syntax). Here's a simple example:
with q as (
select 0 col_a, 1 col_b, 'Rec 1' id from dual
union all
select 1, 0, 'Rec 2' from dual
union all
select 0, 0, 'Rec 3' from dual
)
Select id,
CASE
WHEN COL_A = 0 THEN 'COL_A'
ELSE ''
END||','
||CASE
WHEN COL_B = 0 THEN 'COL_B'
ELSE ''
END "TheString"
from q
Result:
ID TheString
------- -------------------
Rec 1 COL_A,
Rec 2 ,COL_B
Rec 3 COL_A,COL_B

How to only get non numeric part of column out [duplicate]

This question already has answers here:
How to strip all non-alphabetic characters from string in SQL Server?
(21 answers)
Closed 9 years ago.
I have a column called TCODE which has value like 5T, 6545H,25 and S4444.
Now I want only 3 rows out of the 4 rows returned and only the following non numeric bits of those columns T,H or S. Table name is CODES .
Pseudo code
Select TCODE from CODES where I strip out numeric part of those columns where a mix of numeric and non numeric exist.
Expected Results
TCODE
T
H
S
How can I do this ?
In SQL Server, you can possibly use PATINDEX:
SELECT SUBSTRING(TCODE,PATINDEX('%[^0-9]%', TCODE),1)
FROM CODES
WHERE PATINDEX('%[^0-9]%',TCODE) > 0
The way that comes to my mind is the rather brutish:
select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(tcode, '0', ''),
'1', 0),
'2', 0),
'3', 0),
'4', 0),
'5', 0),
'6', 0),
'7', 0),
'8', 0),
'9', 0) as theletters
. . .
You can put this in a subquery, and then select where theletters <> '' for the filtering.
One alternative:
with cte as
(select 0 n, replace(tcode,'0','') tcode from codes
union all
select n+1 n, replace(tcode,convert(varchar,n+1),'') tcode
from cte
where n<9)
select tcode from cte
where n=9
(SQLFiddle here)
You can create a function like this
CREATE FUNCTION RemoveDigits(#strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
WHILE PATINDEX('%[0-9]%', #strText) > 0
BEGIN
SET #strText = STUFF(#strText, PATINDEX('%[0-9]%', #strText), 1, '')
END
RETURN #strText
END
GO
And then use it
SELECT dbo.RemoveDigits(TCODE) TCODE
FROM CODES
WHERE PATINDEX('%[^0-9]%', TCODE) > 0
Output:
| TCODE |
---------
| T |
| H |
| S |
SQLFiddle