I have 2 columns in a single my input as given below :
Input :
Column1
A|B|C|D
Column2
1|2|3|4
And I need to get the single Output as shown below :
Column1
A.1 || B.2 || C.3 || D.4
Can anyone help me to get the output ?
You can split the columns into multiple parts based on delimitter and then concat.
1 find position of | in first column like this -
v_pos1 = InStr( col1, '|', 1, 1)
v_pos2 = InStr( col1, '|', 1, 2)
v_pos3 = InStr( col1, '|', 1, 3)
...
2 Create bunch of variable ports to capture actual values-
v_val1 = iif(v_pos1 =0,col1, SubStr( col1, 1, v_pos1 - 1))
v_val2 = iif(v_pos2 =0,'', SubStr( col1, v_pos1 + 1), SubStr( col1, v_pos1 + 1, v_pos2 - v_pos1 - 1))
v_val2 = iif(v_pos2 =0,'', SubStr( col1, v_pos2 + 1), SubStr( col1, v_pos2 + 1, v_pos3 - v_pos2 - 1))
...
3 Repeat above steps for column2 as well. Lets asseme they are v_val_col21,v_val_col22...
4 Once you have both set of columns, then concat both to get final values.
o_final = v_val1 ||'.' || v_val_col21 ||'||'|| v_val2 ||'.' || v_val_col22...
Related
I have an URL that needs to be shortened. I have 2 formats of the URL, first one is /item/10/0100-, it stops at first -, the second one is /item/12/0100-CAK, it needs 3 more characters after the -.
Below is the example,
/item/10/0100-NAU1X010-10-A032 need to be /item/10/0100-
/item/2/0888-ADBACS11101-2-A048 need to be /item/2/0888-
/item/12/0100-CAK101827812018101-12-A034 need to be /item/12/0100-CAK
/item/3/0110-MSS0016-T03-3-A034 need to be /item/3/0110-MSS
I already try this query
CASE
WHEN Page LIKE "/item/10%" OR Page LIKE "/item/2/%" THEN CONCAT(SUBSTRING_INDEX(SUBSTR(Page, LOCATE('/', Page)+1), '-', 1), "-")
WHEN Page LIKE "/item/12%" OR Page LIKE "/item/3/%" THEN SUBSTRING_INDEX(SUBSTR(Page, LOCATE('/', Page)+1), '-', 1) + 4
ELSE Page
END
But it doesn't give me the right result. It seems simple but I really can't get over it. Please help me with this problem, thank you.
Use string functions in the CASE expression like this:
SELECT
page,
CASE
WHEN Page LIKE '/item/10%' OR Page LIKE '/item/2/%' THEN
CONCAT(SUBSTRING_INDEX(Page, '-', 1), '-')
WHEN Page LIKE '/item/12%' OR Page LIKE '/item/3/%' THEN
CONCAT(SUBSTRING_INDEX(Page, '-', 1), SUBSTR(Page, LOCATE('-', Page), 4))
ELSE Page
END short_Page
FROM tablename
See the demo.
Results:
> page | short_Page
> :--------------------------------------- | :----------------
> /item/10/0100-NAU1X010-10-A032 | /item/10/0100-
> /item/2/0888-ADBACS11101-2-A048 | /item/2/0888-
> /item/12/0100-CAK101827812018101-12-A034 | /item/12/0100-CAK
> /item/3/0110-MSS0016-T03-3-A034 | /item/3/0110-MSS
SELECT Path,
SUBSTRING(Path FROM 1 FOR LOCATE('-', Path) + 3 * (#format = 2)) AS shortened
FROM test;
The format is differentiated by the number after /item/
SELECT Path,
SUBSTRING(Path FROM 1 FOR LOCATE('-', Path) + 3 * (SUBSTRING_INDEX(SUBSTRING_INDEX(Path, '/', 3), '/', -1) IN (12, 3))) AS shortened,
(SUBSTRING_INDEX(SUBSTRING_INDEX(Path, '/', 3), '/', -1) IN (12, 3)) + 1 used_format
FROM test;
Adjust the values list for format 2.
fiddle
I am stuck at a point where i have to increment a string, and my strings are of type C001,SC001,B001
in my data base they are defined like
what i am trying to do do is write a query which check the previous highest code present into my db and the incriment it to +1
for example C001 -> C002,C009->C010,C099`->C100 and so on
Similarly for SC001->SC002,SC009->SC010,SC099->SC100 and so on
Similarly fro B001 -> B002,B009->B010,B099`->B100 and so on
I have a query which my friend has suggested me to use but that query only incriminating AAAA->AAAA01 , AAAA09->AAAA10
query is
SELECT id AS PrevID, CONCAT(
SUBSTRING(id, 1, 4),
IF(CAST(SUBSTRING(id, 5) AS UNSIGNED) <= 9, '0', ''),
CAST(SUBSTRING(id, 5) AS UNSIGNED) + 1
) AS NextID
FROM (
-- since you allow strings such as AAAA20 and AAAA100 you can no longer use MAX
SELECT id
FROM t
ORDER BY SUBSTRING(id, 1, 4) DESC, CAST(SUBSTRING(id, 5) AS UNSIGNED) DESC
LIMIT 1
) x
when i am replacing ID with CategoryCode it is giving me PrevID-C004 NextID-C00401 which is not my requirement i want PrevID-C004 and NextID->C005
NOTE i am using my sqlServer 5.1
Just try this one ,
SELECT
CategoryCode,CAST(CONCAT(LPAD(CategoryCode,1,0),LPAD(MAX(RIGHT(CategoryCode,
3)) + 1, 3, 0) ) AS CHAR),
FROM test
SELECT
SubCategoryCode,CAST(CONCAT(LPAD(SubCategoryCode,2,0),
LPAD(MAX(RIGHT(CategoryCode, 3)) + 1, 3, 0) ) AS CHAR),
FROM test
SELECT
BrandCode,CAST(CONCAT(LPAD(BrandCode,1,0), LPAD(MAX(RIGHT(BrandCode, 3)) +
1, 3, 0)) AS CHAR) FROM test
This query generates next datafile name for a existing schema.
For e.g. id last datafile name is test_schema_05.dbf
then this query gives test_schema_06.dbf
I need to shorten this query .
Is this possible?
SELECT CONCAT
(SUBSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
),
1,
INSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
),
'_',
1,
(LENGTH
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
)
) - LENGTH
(REPLACE
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
),
'_'
)
)
)
)
),
CONCAT
('0',
SUBSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
)
),
INSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
)
),
'_',
1,
(LENGTH
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
)
) - LENGTH
(REPLACE
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
),
'_'
)
)
)
) + 1,
INSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
)
),
'.',
1
) - INSTR
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
)
),
'_',
1,
(LENGTH
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
)
)
) - LENGTH
(REPLACE
(MAX
(SUBSTR
(file_name,
INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
)
),
'_'
)
)
)
) - 1
) + 1
)
)
|| '.dbf' AS data_file_name
FROM dba_data_files
WHERE tablespace_name =
(SELECT default_tablespace
FROM dba_users
WHERE username = 'schema_name'
);
this almost made me cry. Also, it looks like your query is just somewhat wrong, as your MAX functions appear to only contain a single value, which is a string
You have SO MANY repeated lines that are clogging up your query, and your brain when you try to read it. Extract that out to a variable! Assuming this is all inside a sproc somewhere, you end up with something like this:
DECLARE i_intLocation INTEGER;
SET i_intLocation = INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1;
DECLARE i_strSubstr VARCHAR;
SET i_strSubstr = (SUBSTR (file_name, i_intLocation));
SELECT
CONCAT(
SUBSTR(
MAX(i_strSubstr),
1,
INSTR(
MAX(i_strSubstr),
'_',
1,
(
LENGTH(MAX(i_strSubstr))
- LENGTH(
REPLACE(
MAX(i_strSubstr),
'_'
)
)
)
)
),
CONCAT(
'0',
SUBSTR(
MAX(i_strSubstr),
INSTR(
MAX(i_strSubstr),
'_',
1,
(
LENGTH(MAX(i_strSubstr))
- LENGTH(
REPLACE(
MAX(i_strSubstr),
'_'
)
)
)
) + 1,
INSTR(
MAX(i_strSubstr),
'.',
1
)
- INSTR(
MAX(i_strSubstr),
'_',
1,
(
LENGTH(MAX(i_strSubstr))
- LENGTH(
REPLACE(
MAX(i_strSubstr),
'_'
)
)
)
) - 1
) + 1
)
)
|| '.dbf' AS data_file_name
FROM dba_data_files
WHERE tablespace_name =
(SELECT default_tablespace
FROM dba_users
WHERE username = 'schema_name'
);
Using a sub query to get the highest file name to shorten the code it would come out something like this, but I suspect that this is no more efficient (and might well be less efficient).
SELECT CONCAT(SUBSTR(sub1.derived_bit,1,INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit,'_'))))),
CONCAT('0',SUBSTR(sub1.derived_bit,INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit,'_'))))+ 1,INSTR
(sub1.derived_bit,'.',1)- INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit, '_' ))))- 1)+ 1), '.dbf') AS data_file_name
FROM
(
SELECT MAX(SUBSTR(file_name, INSTR(file_name, '/', 1, LENGTH(file_name) - LENGTH(REPLACE(file_name, '/'))) + 1)) as derived_bit
FROM dba_data_files
INNER JOIN dba_users
ON dba_data_files.tablespace_name = dba_users.default_tablespace AND username = 'schema_name'
) sub1
However this is just based on your code which has syntax errors (which I have just repeated in my code above). For example your code is using INSTR with 4 parameters (should only have 2). Similarly you are using REPLACE with only 2 parameters. Your functions are looking for '/' while the file names you give as example do not contain any '/' characters.
How fixed is the format of the file name? Is there only ever 1 . in the file name? Is the number to increment always immediatly before the .dbf?
I have a mysql query:
SELECT my_table.* WHERE SOUNDEX(my_col)='whatever' OR SUBSTR(SOUNDEX(my_col),4)='whatever' ORDER BY SUBSTR(SOUNDEX(my_col),4)='whatever',SOUNDEX(my_col)='whatever'
How many times will the substring function and soundex functions will actually be called? I mean for exactly same inputs will mysql cache the results over the span of one query?
If not, how can I make the change in the query so that each function is called minimum times possible.
MySQL would call this function four times for every returned row, to avoid this you can use a subquery, so instead of
SELECT *
FROM song
ORDER BY Substr(pre_calculated_soundex, 1, 1) =
Substr(Soundex("aaaa"), 1, 1)
+ Substr(pre_calculated_soundex
, 2, 1) =
Substr
(Soundex("aaaa"), 2, 1)
+ Substr(pre_calculated_soundex, 3, 1)
= Substr(Soundex("aaaa"), 3, 1)
+ Substr(pre_calculated_soundex, 4, 1
)
= Substr(Soundex("aaaa"), 4, 1)
You can do
SELECT * from (select *, Soundex("aaaa") as current_soundex from song)
ORDER BY
Substr(pre_calculated_soundex, 1, 1) = Substr(current_soundex , 1, 1)
+ Substr(pre_calculated_soundex, 2, 1) = Substr(current_soundex , 2, 1)
+ Substr(pre_calculated_soundex, 3, 1) = Substr(current_soundex , 3, 1)
+ Substr(pre_calculated_soundex, 4, 1) = Substr(current_soundex , 4, 1)
I need to concatenate from two different tables.
Compare s.panelid (result like "AA") to b.modulecodes and return number_of_strings. Then put s.panelid (result like "AA") and number_of_string together.
select concat(Mid(s.panelid, 5, 2), ' - ' , '??') as `Module Type-Strings`
from r2rtool.stringtopanel s, be.modulecodes b
where s.insertts > '2011-07-15' and s.insertts < '2011-07-26' and Mid(s.panelid, 5, 2) != 99
group by date(insertts), `Module Type-Strings`
order by `Module Type-Strings`;
Be (Table): modulecodes, number_of_strings
AA - 12
AB - 4
AD - 3
AE - 12
When I run the above query it returns things like: Module Type-Strings = 'AA-??' and "AB-??" of course.
I am looking for: Module Type-Strings = 'AA-12'
Just in case you haven't tried it already...
Have you tried this?
select concat(Mid(s.panelid, 5, 2), ' - ' , b.number_of_string) as `Module Type-Strings`
from r2rtool.stringtopanel s, be.modulecodes b
where s.insertts > '2011-07-15' and s.insertts < '2011-07-26' and Mid(s.panelid, 5, 2) != 99
group by date(insertts), `Module Type-Strings`
order by `Module Type-Strings`;
There I'm basically replacing the '??' with the column you are asking about, number_of_string in the be.modulecodes table (aliased as b in the from clause).