splitting the source data to have the specific data oracle - oracle-sqldeveloper

I have a source field from oracle db table data type VARCHAR2(512 CHAR) which is like this
%custId{str:hGl0EWJsRTwweerRkaaKsdKDsqKm0123}
%prod{str:BalanceAmount}%logistic{str:Logistic}%hiringdate{str:1999-02-28T11:10:11p}%custId{str:FpseikiD0Jt1L0Mskdww8oZBjU4La123}
but when i consider for my extract i must only consider only data with %cusId pull data and only this alphanumeric data has to be captured and populated for the extract , the problem is this is just one example from source there can be any number of combinations but i have to only consider %custId with
%custId{str:hGl0EWJsRTwweerRkaaKsdKDsqKm0123}
i need to use which function substr,lpad ?
after using the below query
SELECT
field,
REGEXP_SUBSTR(field, '%custId\{.*?\}') AS custId
FROM yourTable
where col_source='%prod{str:BalanceAmount}%logistic{str:Logistic}%hiringdate{str:1999-02-28T11:10:11p}%custId{str:FpseikiD0Jt1L0Mskdww8oZBjU4La123}'
Result
%custId{str:FpseikiD0Jt1L0Mskdww8oZBjU4La123}
but expected result
FpseikiD0Jt1L0Mskdww8oZBjU4La123

You may use REGEXP_SUBSTR here:
SELECT
field,
REGEXP_SUBSTR(field, '%custId\{(.*?)\}', 1, 1, NULL, 1) AS custId
FROM yourTable;

Related

Postgres, where in on a json object

I've been looking around and can't seem to find anything that is helping me understand how I can achieve the following. (Bear in mind I have simplified this to the problem I'm having and I am only storing simple JSON objects in this field)
Given I have a table "test" defined
CREATE TABLE test (
id int primary key
, features jsonb
)
And some test data
id
features
1
{"country": "Sweden"}
2
{"country": "Denmark"}
3
{"country": "Norway"}
I've been trying to filter on the JSONB column "features". I can do this easily with one value
SELECT *
FROM test
WHERE features #> '{"country": "Sweden"}'
But I've been having troubles working out how I could filter by multiple values succintly. I can do this
SELECT *
FROM test
WHERE features #> '{"country": "Sweden"}'
OR features #> '{"country": "Norway"}'
But I have been wondering if there would be an equivalent to WHERE IN ($1, $2, ...) for JSONB columns.
I suspect that I will likely need to stick with the WHERE... OR... but would like to know if there is another way to achieve this.
You can use jsonb->>'field_name' extract a field as text, then you use any operator compatible with text type
SELECT *
FROM test
WHERE features->>'country' = 'Sweden'
SELECT *
FROM test
WHERE features->>'country' in ('Sweden', 'Norway')
You an also directly work with jsonb as follow
jsonb->'field_name' extract field as jsonb, then you can use operator compatible with jsonb:
SELECT *
FROM test
WHERE features->'country' ?| array['Sweden', 'Norway']
See docs for more details
You can extract the country value, then you can use a regular IN condition:
select *
from test
where features ->> 'country' in ('Sweden', 'Norway')

Like operation on Json object in postgresql

I have the JSON column in my table which is having array's of dictionary. The array has standard format.
[{'path': 'chat/xyz.pdf', 'file_name': 'xyz.pdf'},
{'path': 'chat/xyl.pdf', 'file_name': 'xyl.pdf'}]
The table name is chat and column name is attachments. I want to perform search on file names such that even if i type one letter is typed then that row should be retrieved. For example: if i search by string 'pd' then all values with file_name having 'pd' string should be retrieved.
I tried this and it did work.
select distinct attachments from chat, jsonb_array_elements_text(attachments)
where value::json->>'file_name' like '%xyz%';
I took reference from documentation.
You can use an EXISTS condition, then you don't need the DISTINCT:
select c.*
from chat c
where exists (select *
from jsonb_array_elements(c.attachments) as t(doc)
where t.doc ->> 'file_name' like '%xyz%');

Use SQL to Evaluate XML string broken into several rows

I have an application that stores a single XML record broken up into 3 separate rows, I'm assuming due to length limits. The first two rows each max out the storage at 4000 characters and unfortunately doesn't break at the same place for each record.
I'm trying to find a way to combine the three rows into a complete XML record that I can then extract data from.
I've tried concatenating the rows but can't find a data type or anything else that will let me pull the three rows into a single readable XML record.
I have several limitations I'm up against as we have select only access to the DB and I'm stuck using just SQL as I don't have enough access to implement any kind of external program to pull the data that is there an manipulate it using something else.
Any ideas would be very appreciated.
Without sample data, and desired results, we can only offer a possible approach.
Since you are on 2017, you have access to string_agg()
Here I am using ID as the proper sequence.
I should add that try_convert() will return a NULL if the conversion to XML fails.
Example
Declare #YourTable table (ID int,SomeCol varchar(4000))
Insert Into #YourTable values
(1,'<root><name>XYZ Co')
,(2,'mpany</')
,(3,'name></root>')
Select try_convert(xml,string_agg(SomeCol,'') within group (order by ID) )
From #YourTable
Returns
<root>
<name>XYZ Company</name>
</root>
EDIT 2014 Option
Select try_convert(xml,(Select '' + SomeCol
From #YourTable
Order By ID
For XML Path(''), TYPE).value('.', 'varchar(max)')
)
Or Even
Declare #S varchar(max) = ''
Select #S=#S+SomeCol
From #YourTable
Order By ID
Select try_convert(xml,#S)

Store the whole query result in variable using postgresql Stored procedure

I'm trying to get the whole result of a query into a variable, so I can loop through it and make inserts.
I don't know if it's possible.
I'm new to postgre and procedures, any help will be very welcome.
Something like:
declare result (I don't know what kind of data type I should use to get a query);
select into result label, number, desc from data
Thanks in advance!
I think you have to read PostgreSQL documentation about cursors.
But if you want just insert data from one table to another, you can do:
insert into data2 (label, number, desc)
select label, number, desc
from data
if you want to "save" data from query, you also can use temporary table, which you can create by usual create table or create table as:
create temporary table temp_data as
(
select label, number, desc
from data
)
see documentation

Hive: How to do a SELECT query to output a unique primary key using HiveQL?

I have the following schema dataset which i want to transform into a table that can be exported to SQL. I am using HIVE. Input as follows
call_id,stat1,stat2,stat3
1,a,b,c,
2,x,y,z,
3,d,e,f,
1,j,k,l,
The output table needs to have call_id as its primary key so it needs to be unique. The output schema should be
call_id,stat2,stat3,
1,b,c, or (1,k,l)
2,y,z,
3,e,f,
The problem is that when i use the keyword DISTINCT in the HIVE query, the DISTINCT applies to the all the colums combined. I want to apply the DISTINCT operation only to the call_id. Something on the lines of
SELECT DISTINCT(call_id), stat2,stat3 from intable;
However this is not valid in HIVE(I am not well-versed in SQL either).
The only legal query seems to be
SELECT DISTINCT call_id, stat2,stat3 from intable;
But this returns multiple rows with same call_id as the other columns are different and the row on the whole is distinct.
NOTE: There is no arithmetic relation between a,b,c,x,y,z, etc. So any trick of averaging or summing is not viable.
Any ideas how i can do this?
One quick idea,not the best one, but will do the work-
hive>create table temp1(a int,b string);
hive>insert overwrite table temp1
select call_id,max(concat(stat1,'|',stat2,'|',stat3)) from intable group by call_id;
hive>insert overwrite table intable
select a,split(b,'|')[0],split(b,'|')[1],split(b,'|')[2] from temp1;
,,I want to apply the DISTINCT operation only to the call_id"
But how will then Hive know which row to eliminate?
Without knowing the amount of data / size of the stat fields you have, the following query can the job:
select distinct i1.call_id, i1.stat2, i1.stat3 from (
select call_id, MIN(concat(stat1, stat2, stat3)) as smin
from intable group by call_id
) i2 join intable i1 on i1.call_id = i2.call_id
AND concat(i1.stat1, i1.stat2, i1.stat3) = i2.smin;