How To Substring and Add a Range - mysql

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

Related

How to auto increment a string with sql query

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

Ordering by inches value in MYSQL

I've searched for the answer to this but can't quite work it out. I think I'm close but need your help please.
I have the following mysql query:
SELECT `size`
FROM `table`
GROUP BY `size`
ORDER BY CONVERT(SUBSTR(size, 1, POSITION('/' IN size) - 1), UNSIGNED INTEGER) ASC,
SUBSTRING_INDEX(size,'/',1)/SUBSTRING_INDEX(size,'/',-1) ASC
Running this gives the following result:
1"
2"
4"
3"
1/2"
3/8"
3/4"
11/4"
11/2"
21/2"
I need the sizes to come out smallest to largest. Any help on this would be massively appreciated. Thank you.
Note, I have also tried removing the " from the sizes in the database and the result was exactly the same.
An example of the dataset:
1 1/2"
1 1/4"
1"
1/2"
1/4"
1/8"
10"
11/2"
11/4"
11/4""
12"
14"
16"
2 1/2"
2"
21/2"
3"
3/4"
3/8"
4"
5"
6"
8"
Lovely data format. I think you are going to have to do the division. The calculation is something like this:
order by (case when size like '%/%'
then (substring_index(size, '/', 1) + 0) / (substring_index(size, '/', 2) + 0)
else size + 0
end)
Even if the " is part of the field, this will still work. The + 0 does "silent" conversion. That is, it converts the string up to the first non-numeric character.
EDIT:
If you could have spaces with whole numbers first, you would do:
order by (case when size like '% %/%'
then (substring_index(size, 1, ' ') + 0) +
((substring_index(substring_index(size, ' ', 2), '/', 1) + 0) /
(substring_index(size, '/', -1) + 0)
)
when size like '%/%'
then (substring_index(size, '/', 1) + 0) / (substring_index(size, '/', 2) + 0)
else size + 0
end)
You query almost work. However in first part of the order by you should substract the position from the string length.
SELECT `size`
FROM `size`
GROUP BY `size`
ORDER BY CONVERT(SUBSTR(size, 1, LENGTH(size) - POSITION('/' IN size) - 1), UNSIGNED INTEGER) ASC,
SUBSTRING_INDEX(size,'/',1)/SUBSTRING_INDEX(size,'/',-1) ASC
http://sqlfiddle.com/#!2/cd0658/6

Parse text using substring in mysql

I want to parse a text using substring. The format we have for the text is like this:
N, Adele, A, 18
And the substring we do is like this:
SUBSTRING_INDEX(SUBSTRING_INDEX(text, ',', 2), ', ', -1) as 'Name',
SUBSTRING_INDEX(SUBSTRING_INDEX(text, ',', 4), ', ', -1) as 'Age',
The output we get is:
| Name | Age |
| Adele | 18 |
But we want to change the text format to:
N Adele, A 18
What would be the correct syntax so can I parse the text in the position 1 (N Adele) and use the delimiter space and just get Adele? And then same for the next text (A 18)?
I tried doing
SUBSTRING_INDEX(SUBSTRING_INDEX(text, ' ', 1), ', ', -1) as 'Name',
But the output I got is just
| Name |
| N |
The output I was hoping for is like this:
| Name |
| Adele |
Presuming here that you want to change your original data structure and still be able to get the results out. You change your data structure to:
N Adele, A 18 -- etc
With the potential to have multiple names as the name (space separated), my previous example is not correct.
You could trim off the N and A directly with their space, knowing that they will only ever be two characters long and that they will always be there, like this:
SUBSTRING(TRIM(SUBSTRING_INDEX(`text`, ',', 1)), 3) AS 'Name',
SUBSTRING(TRIM(SUBSTRING_INDEX(`text`, ',', -1)), 3) AS 'Age'
To get:
Name | Age
--------------------
Adele | 18
You can use
SELECT
SUBSTRING(text, 2, INSTR(text, ',') - INSTR(text, ' ')) AS Name,
SUBSTRING(text, INSTR(text, ',') + 3, LENGTH(text) - INSTR(text, ',') + 3) AS Age
FROM your_table;
as the position of the field descriptors (N and A) are fixed (relative to the start of the string and to the comma). You can check the working query in this fiddle.

Convert IP address (IPv4) itno an Integer in R

I was looking for a way to write a function in R which converts an IP address into an integer.
My dataframe looks like this:
total IP
626 189.14.153.147
510 67.201.11.8
509 64.22.53.140
483 180.9.85.10
403 98.8.136.126
391 64.06.187.68
I export this data from mysql database. I have a query where i can convert an IP address into an integer in mysql:
mysql> select CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 1), '.', -1) << 24 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 2), '.', -1) << 16 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 3), '.', -1) << 8 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 4), '.', -1) AS UNSIGNED) FINAL;
But I want to do this conversion in R, any help would be awesome
You were not entirely specific about what conversion you wanted, so I multiplied the decimal values by what I thought might appropriate (thinking the three digit items were actually digit equivalents in "base 256" numbers then redisplayed in base 10). If you wanted the order of the locations to be reversed, as I have seen suggested elsewhere, you would reverse the indexing of 'vals' in both solutions
convIP <- function(IP) { vals <- read.table(text=as.character(IP), sep=".")
return( vals[1] + 256*vals[2] + 256^2*vals[3] + 256^3*vals[4]) }
> convIP(dat$IP)
V1
1 2476281533
2 134990147
3 2352289344
4 173345204
5 2122844258
6 1153107520
(It's usually better IT practice to specify what you think to be the correct answer so testing can be done. Bertelson's comment above would be faster and implicitly uses 1000, 1000^2 and 1000^3 as the factors.)
I am taking a crack at simplifying the code but fear that the need to use Reduce("+", ...) may make it more complex. You cannot use sum because it is not vectorized.
convIP <- function(IP) { vals <- read.table(text=as.character(IP), sep=".")
return( Reduce("+", vals*256^(3:0))) }
> convIP(dat$IP)
[1] 5737849088 5112017 2717938944 1245449 3925902848 16449610

Concat different tables?

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).