Select Only Characters after First Character in String - sql

Sample results before string manipulation:
COLUMN1 |
-----------
A343jsk |
------------
Jsdefss |
------------
Vdkekd |
------------
Nod |
------------
An |
------------
How do I achieve:
343jsk |
------------
sdefss |
-----------
dkekd |
-----------
od |
-----------
n |
-----------
I tried this:
SELECT
COLUMN1 - LEFT(COLUMN1,1)
FROM
Table
however this does not work. Obviously I can't use RIGHT because result strings are not all the same length.

Use SUBSTRING():
SELECT
SUBSTRING(COLUMN1, 2, LEN(COLUMN1) - 1)
FROM
Table
Alternatively, (as #David Faber pointed out) you could use:
SELECT
RIGHT(column1, LEN(column1) - 1)
FROM
Table
[I personally prefer the first form]

Related

Is there any better way to display the value of the table without creating too many VIEW?

so I want the following table to be differentiate using a new column that follows its stage code. For example:
Original Data
|JS_CASEKEY|JS_STAGE_CODE|JS_ENDDATE |
| -------- | ----------- | --------- |
| 0001 | ARRCV1 | 20/02/2022|
| 0002 | CUSTEXEC | 01/02/2022|
| 0003 | ARRCV1 | <NULL> |
Expected Results
|JS_CASEKEY|ARRCV1 END DATE|CUSTEXEC END DATE|
| -------- | ------------- | ----------------|
| 0001 | 20/02/2022 | <NULL> |
| 0002 | <NULL> | 01/02/2022 |
| 0003 | <NULL> | <NULL> |
As for now my solution were creating two different VIEW for each of the different stage code but in terms of maintainability would be a hassle if the stage code got many different values.
The code for the view are as follows
CREATE OR REPLACE VIEW VW_CUSTEXEC_ENDDATE AS select JS_CASEKEY,
JS_ENDDATE from jcheckstage where js_stage_code = 'CUSTEXEC';
CREATE OR REPLACE VIEW VW_ARRCV1_ENDDATE AS select JS_CASEKEY as
JS_CASEKEY1, JS_ENDDATE as JS_ENDDATE1 from jcheckstage where
js_stage_code = 'ARRCV1';
Then in the select statement I would just include the following to make use of the two VIEWs i created
select JS_ENDDATE as "Customer Execution End Date", JS_ENDDATE1
as "AR 1 End Date";
This method would be okay to maintain if there is only few different values for the stage code but any more values for it would mean a lot more VIEWs to create and are going to be hard to manage. Is there a simpler way to do this or any other way that I didn't discover yet?
You can use some code like this:
with data ( JS_CASEKEY,JS_STAGE_CODE,JS_ENDDATE ) as (
select '0001' , 'ARRCV1' , '20/02/2022' from dual union all
select '0002' , 'CUSTEXEC' , '01/02/2022' from dual union all
select '0003' , 'ARRCV1' ,null from dual
)
select
JS_CASEKEY, max(case when JS_STAGE_CODE='ARRCV1' then JS_ENDDATE else null end) as arrcv_end_date,
max(case when JS_STAGE_CODE='CUSTEXEC' then JS_ENDDATE else null end) as CUSTEXEC_end_date
from data
group by JS_CASEKEY
/
JS_C ARRCV_END_ CUSTEXEC_E
---- ---------- ----------
0001 20/02/2022
0002 01/02/2022
0003
or also use pivot, like this
select *
from data
pivot (max(JS_ENDDATE) for JS_STAGE_CODE in ('ARRCV1' as arrcv_end_date, 'CUSTEXEC' as CUSTEXEC_end_date))

BigQuery get all values in a range

I have a column that can contains a range and I want to get all values in that range. I.e
I have the following records
id | number
-------------
1 | 342-345
-------------
2 | 346
And a want it in the following format:
id | number
-------------
1 | 342
| 343
| 344
| 345
-------------
2 | 346
I am using Standard SQL.
You can use split() to split the string and then generate_array() to get the values you want:
select t.*,
GENERATE_ARRAY(cast(split(numbers, '-')[ordinal(1)] as int64),
cast(COALESCE(split(numbers, '-')[SAFE_ORDINAL(2)], split(numbers, '-')[ordinal(1)]) as int64),
1)
from (select 1 as id, '342-345' as numbers UNION ALL
SELECT 2, '346'
) t;

Order sql result by first occurence of string

Given the following sql statement:
select * from mytable where mycolumn like '%xyz%'
and the following result
aaxyz
bbbxyz
xyzcc
dxyzxd
eeeeexyz
How do I demand the sql statement to order the result in the rank of the first occurence of the demanded string, i.e. xyzcc first and eeeeexyz last?
With the function position() which returns the index of the first occurrence of a substring inside a string:
select * from mytable
where mycolumn like '%xyz%'
order by position('xyz' in mycolumn)
See the demo.
Results:
| mycolumn |
| -------- |
| xyzcc |
| dxyzxd |
| aaxyz |
| bbbxyz |
| eeeeexyz |

Retrieve field offset via recursive query in db2

Assume that I've got key-value table of field_name-field_len pair.
As follows:
-----------------------------------
field_name | field_len |
-----------------------------------
FIELD_A | 10 |
-----------------------------------
FIELD_B | 20 |
-----------------------------------
...
-----------------------------------
FIELD_X | 2 |
-----------------------------------
FIELD_Y | 100 |
-----------------------------------
Then I need an offset of each field to be in third column.
Like this:
-----------------------------------------------------
field_name | field_len | offset |
-----------------------------------------------------
FIELD_A | 10 | 0 |
-----------------------------------------------------
FIELD_B | 20 | 10 |
-----------------------------------------------------
...
-----------------------------------------------------
FIELD_X | 2 | 250 |
-----------------------------------------------------
FIELD_Y | 100 | 252 |
-----------------------------------------------------
So I've wrote this script based on some manuals (1,2):
with offsets (column_name, length, offset) as
((select column_name, length, CAST(0 AS SMALLINT)
from myschema.sizes a
start with rrn(a) = 1)
union all
(select b.column_name, b.length, offset + o.length
from offsets o, myschema.sizes b
where rrn(b) between 2 and 100))
select * from offsets;
However, it keeps getting into infinite loop.
Also this version gives same result:
with offsets (column_name, length, offset) as
((select column_name, length, CAST(0 AS SMALLINT)
from myschema.sizes a
fetch first row only)
union all
(select b.column_name, b.length, offset + o.length
from offsets o join myschema.sizes b on b.column_name = o.column_name
where o.column_name <>'LAST_FIELD'))
select * from offsets;
I guess, that messed somewhere with exit condition, but can not figure exact place to fix it.
Would be great to avoid any table specific metadata like row count too.
You don't need a recursive CTE for this. Just a cumulative sum. Something like this:
select s.*,
(sum(field_len) over (order by rrn(s)) - field_len) as offset
from myschema.sizes s;
I'm not sure how the ordering is defined. It seems to be based on a function rrn().

Oracle Sql; Find same combination of columnvalues in two or more rows

I need some help with my query. Been searching for ages but can`t come up with the right sql statement.
This my table DRAFT DFT (only 1 table, these are all the columns)
RowID|SID Number|Column C|RELS Number|Column E|Dr Number |Column G |
1------ | 23101----- |21-8-2014| 22234 ----- | UNR---------| 14243-----|2
2------ | 23101 ----- |22-8-2014| 22234 ----- | UNS---------| 14243 ---| 2
3------ | 23101------ |28-8-2014| 22232 ----- | FRE ---------| 14243 ---| 2
What I need is the following :
I need to select all the rows & Columns values of the table where the combination of the value in column SID Number and RELS Number are duplicate so what I must see is ony the following 2 rows:
1------ | 23101----- |21-8-2014| 22234 ----- | UNR---------| 14243-----|2
2------ | 23101 ----- |22-8-2014| 22234 ----- | UNS---------| 14243 ---| 2
AND NOT THIS:
1------ | 23101----- |21-8-2014| 22234 ----- | UNR---------| 14243-----|2
2------ | 23101 ----- |22-8-2014| 22234 ----- | UNS---------| 14243 ---| 2
**3------ | 23101------ |28-8-2014| 22232 ----- | FRE ---------| 14243 ---| 2**
because the combination of SID Number and RELS Number is not duplicate.
I know that the column value of Dr Number is the same in all 3 rows.
Does that matter for my sql statement?
This was my statement:
SELECT *
FROM DRAFT DFT
INNER JOIN (SELECT SID Number,RELS Number, COUNT(*) AS "TOTALCOUNT
FROM DRAFT DTF1GROUP BY SID Number,RELS Number
HAVING COUNT (*)>1
) B ON DTF.SID Number=B.SID Number AND DTF.RELS Number=B.RELS Number
Just use analytic functions:
select d.*
from (select d.*, count(*) over (partition by sid, rels) as cnt
from draft
) d
where cnt > 1;