Split string into row - sql

I am using MySQL.
I have a table named "class", the "class" table has three columns name , year and class_code like following:
Class table:
Now I would like to use the above table to create a new table named "temp", which contains class_code and value columns.
The rule is that each string value in each column field of a row of the above "class" table will be split into words, and each word will be inserted to the "temp" table as value column of a temp table record like following:
temp table:
I am using MySQL.
Is it possible to generate the "temp" table purely by using SQL statement and how?
That's :
CREATE TABLE temp;
ALTER TABLE temp DISABLE KEYS;
INSERT INTO ...(how to split the string value of each field in "class" table and insert to "temp" table??? )
P.S.:
I used a simple equal length string as a value, but the actually case has very random length string, and the number of words in each string is random also.

CREATE TABLE new_table
SELECT SUBSTRING(name, 1, 4) as field, class_code FROM old_table
UNION
SELECT SUBSTRING(name, 6, 4) as field, class_code FROM old_table
UNION
SELECT SUBSTRING(name, 11, 4) as field, class_code FROM old_table
UNION
SELECT SUBSTRING(year, 1, 4) as field, class_code FROM old_table
UNION
SELECT SUBSTRING(year, 6, 4) as field, class_code FROM old_table

You have to write a function for string splitting in MySql as
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
And use it to split the values and do the assigning the splitted values and inserting in to table in a SP.For more information refer to the MySQL Split String

Related

How determine if range list contains specified integer

Product type table contains product types. Some ids may missing :
create table artliik (liiginrlki char(3) primary key);
insert into artliik values('1');
insert into artliik values('3');
insert into artliik values('4');
...
insert into artliik values('999');
Property table contais comma separated list of types.
create table strings ( id char(100) primary key, kirjeldLku chr(200) );
insert into strings values ('item1', '1,4-5' );
insert into strings values ('item2', '1,2,3,6-9,23-44,45' );
Type can specified as single integer, e.q 1,2,3 or as range like 6-9 or 23-44
List can contain both of them.
How to all properties for given type.
Query
select id
from artliik
join strings on ','||trim(strings.kirjeldLku)||',' like '%,'||trim(artliik.liiginrlki)||',%'
returns date for single integer list only.
How to change join so that type ranges in list like 6-9 are also returned?
Eq. f list contains 6-9, Type 6,7,8 and 9 shoud included in report.
Postgres 13 is used.
I would suggest a helper function similar to unnest that honors ranges.
Corrected function
create or replace function unnest_ranges(s text)
returns setof text language sql immutable as
$$
with t(x) as (select unnest(string_to_array(s, ',')))
select generate_series
(
split_part(x, '-', 1)::int,
case when x ~ '-' then split_part(x, '-', 2)::int else x::int end,
1
)::text
from t;
$$;
Then you can 'normalize' table strings and join.
select *
from artliik a
join (select id, unnest_ranges(kirjeldLku) from strings) as t(id, v)
on a.liiginrlki = v;
The use of a function definition is of course optional. I prefer it because the function is generic and reusable.
dbfiddle.uk demo will only works on pg14, since only pg14 have multirange data type. But customizeable icu collation works in pg13.
Collation doc: https://www.postgresql.org/docs/current/collation.html
Idea: create a multirange text data type that will sort numeric value based on their numerical value. like 'A-21' < 'A-123'.
CREATE COLLATION testcoll_numeric (
provider = icu,
locale = '#colNumeric=yes'
);
CREATE TYPE textrange AS RANGE (
subtype = text,
multirange_type_name = mulitrange_of_text,
COLLATION = testcoll_numeric
);
So
SELECT
mulitrange_of_text (textrange ('1'::text, '11'::text)) #> '9'::text AS contain_9;
should return true.
artliik table structure remain the same, but strings table need to change a bit.
CREATE temp TABLE strings (
id text PRIMARY KEY,
kirjeldLku mulitrange_of_text
);
then query it:
SELECT DISTINCT
strings.id
FROM
artliik,
strings
WHERE
strings.kirjeldLku #> liiginrlki::text
ORDER BY
1;

Not able to insert a row in a table which has auto incremented primary key

I have a table reportFilters which has the following column names:
The reportFilterId is auto increment. I want to insert a row in the table with the script below:
IF OBJECT_ID(N'ReportFilters', N'U') IS NOT NULL
BEGIN
IF NOT EXISTS (SELECT * FROM [ReportFilters]
WHERE ReportId IN (SELECT ReportId FROM [Reports] WHERE ReportType = 'Operational Insights Command Staff Dashboard') )
BEGIN
INSERT INTO [ReportFilters] Values(1, 'SelectView', 'Select Views', 13, 'Views','Views', 'SelectView', 'a', 'b', 'c' );
END
END
GO
But I am getting the following error:
Column name or number of supplied values does not match table definition.
Can I please get help on this ? Thanks in advance.
I think the problem is on inserted columns can't match with inserted data because that will instead by your table column order which is ReportFilterId instead of ReportId
So that there are 11 columns in your table but your statement only provides 10 columns.
I would use explicitly specify for inserted columns (inserted columns start from ReportId except your PK ReportFilterId column)
INSERT INTO [ReportFilters] (ReportId,ReportFilterName,ReportFilterTitle....)
Values (1, 'SelectView', 'Select Views', 13, 'Views','Views', 'SelectView', 'a', 'b', 'c' );

how to split column of table in select command in sql

i have column in one table with string value than string value splited with ','
my table is like this:
id strColumn
1 abc,def,egh,asa,plok
I want the character string to be separated using the split function when placed in the selection command and placed in a table as follows
newColumn
abc
def
egh
asa
plok
USE tempdb
GO
IF OBJECT_ID(N'tempdb..#Test',N'U')IS NOT NULL
DROP TABLE tempdb..#Test;
CREATE TABLE #Test
(
ID TINYINT NOT NULL,
StrColumn VARCHAR(50)
)
INSERT #Test(ID,StrColumn)
VALUES(1,'abc,def,egh,asa,plok');
SELECT T.ID,VALUE
FROM #Test AS T
CROSS APPLY STRING_SPLIT(StrColumn, ',');
DROP TABLE #Test;
Fro SQL Server 2016 and later you can use STRING_SPLIT-function (example is above)

Oracle database 12c : ORACLE JSON QUERY SEARCH

Creating two types of table to store JSON values (BLOB and NCLOB) and my aim to search the required values from JSON table;
Code Snippet 1: Creating table with one column as NCLOB.
create table departments_json_nclob (
department_id integer not null primary key,
department_data NCLOB not null
);
Simple insert with multibyte character (that is value : məharaːʂʈrə):
insert into departments_json_nclob
values ( 200,'{"department_list":[{"Deptname":"DEPT-A", "value" : "məharaːʂʈrə"}]}');
Code Snippet 2: Now, I have created one other table with BLOB datatype:
create table departments_json (
department_id integer not null primary key,
department_data blob not null
);
Added constraint to allow only JSON
alter table departments_json
add constraint dept_data_json
check ( department_data is JSON FORMAT JSON STRICT );
Insert normal JSON
insert into departments_json
values ( 100, utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" : "məharaːʂʈrə"}]}'));
Insertion Verified from below query:
SELECT json_value(department_data format json, '$.department_list.value' )
FROM departments_json JS
WHERE DEPARTMENT_ID=100;
output is: məharaːʂʈrə
Now, I will have one more insertion in same table i.e. 'departments_json' but this time I will take required insertion value from NCLOB table departments_json_nclob:
declare
i nclob;
begin
select department_data into i from departments_json_nclob where department_id =200;
--inserting same way as I inserted in departments_json for department_id 100 but value comes from NCLOB
insert into departments_json
values ( 101, utl_raw.cast_to_raw (i));
commit;
end;
Again, insertion verified with below query:
SELECT json_value(department_data format json, '$.department_list.value' )
FROM departments_json JS
WHERE DEPARTMENT_ID=101;
output is: məharaːʂʈrə
Now my question is:
When I search for multibyte character, query return result of one query only that is direct insertion in BLOB table. Which is DEPARTMENT_ID=100 - why not 101?
Below query:
SELECT *
FROM departments_json
WHERE JSON_value(department_data format json, '$.department_list.value') = ('məharaːʂʈrə');
SELECT *
FROM departments_json
WHERE JSON_TEXTCONTAINS(department_data, '$.department_list.value', 'məharaːʂʈrə')
below query shows which character are multibyte:
select c, length(c), lengthb(c)
from ( select substr(s, level, 1) c
from ( select 'məharaːʂʈrə' s
from dual)
connect by level <= length(s));

Separate numbers and [] data in a column

I have a data in one of the column looks like this ALAN, DONALD[1234], I need to split this into two columns like Name( ALAN,DONALD), ID (1234)
I tried the following code and I was able to get the ID but not the name
create table #test(NAME_ID VARCHAR(50))
INSERT INTO #TEST VALUES ('ALAN,DONALD [1234])' )
SELECT CAST (substring(NAME_ID,charindex('[',NAME_ID)+1,charindex(']',NAME_ID)-charindex('[',NAME_ID)-1) AS VARCHAR (102) ) AS MRN FROM #TEST
You could do it based on the index of the bracket:
SELECT
RTRIM(SUBSTRING(NAME_ID, 0, CHARINDEX('[',NAME_ID))) AS Name,
CAST (SUBSTRING(NAME_ID,CHARINDEX('[',NAME_ID)+1,CHARINDEX(']',NAME_ID)-
CHARINDEX('[',NAME_ID)-1) AS VARCHAR (102) ) AS MRN
FROM #TEST