cast(SUBSTRING with decimal - sql-server-2008

I have this line that works and gets my column into a number
case when Auth_Amt LIKE '%DAY%' then cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION('/DAY' IN Auth_Amt) - 1) as numeric) when Auth_Amt LIKE '%TAX%' then cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION(' ' IN Auth_Amt) - 1) as numeric)
when Auth_Amt LIKE '%SCHG%' then cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION(' ' IN Auth_Amt) - 1) as numeric)
else 0
end as Amt_Day
what can I add to this to make it come back with two decimal spots also. Right now it is whole numbers bring back.

You can try like this:
case when Auth_Amt LIKE '%DAY%' then CAST(cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION('/DAY' IN Auth_Amt) - 1) as decimal(13,2)) as decimal(13,2))
when Auth_Amt LIKE '%TAX%' then CAST(cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION(' ' IN Auth_Amt) - 1) as decimal(13,2)) as decimal(13,2))
when Auth_Amt LIKE '%SCHG%' then CAST(cast(SUBSTRING(Auth_Amt FROM 1 FOR POSITION(' ' IN Auth_Amt) - 1) as decimal(13,2)) as decimal(13,2))
else 0
end as Amt_Day
In general you have to CAST it like this:
CAST(yourField as decimal(13,2))

Related

How To Substring and Add a Range

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

T-SQL - fiscal quarter

I want to arrive at an output like 2011-Q4 (Financial Yr-Qtr)
I can do this by:
CASE -- Results: 2011-Q4 (Financial Yr-Qtr)
WHEN MONTH(MyDate) BETWEEN 1 AND 3 THEN concat((YEAR(MyDate) - 1), '-', 'Q4')
WHEN MONTH(MyDate) BETWEEN 4 AND 6 THEN concat((YEAR(MyDate) - 1), '-', 'Q1')
WHEN MONTH(MyDate) BETWEEN 7 AND 9 THEN concat((YEAR(MyDate) - 0), '-', 'Q2')
WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN concat((YEAR(MyDate) - 0), '-', 'Q3')
END AS FYrQtr
But can the same output be achieved without using CONCAT? (I only have 2008 at work; CONCAT arrived in 2012).
Thanks.
In this particular case you can simply use the + operator plus some cast():
CASE -- Results: 2011-Q4 (Financial Yr-Qtr)
WHEN MONTH(MyDate) BETWEEN 1 AND 3 THEN cast(YEAR(MyDate) - 1 as char(4)) + '-Q4'
WHEN MONTH(MyDate) BETWEEN 4 AND 6 THEN cast(YEAR(MyDate) - 1 as char(4)) + '-Q1'
WHEN MONTH(MyDate) BETWEEN 7 AND 9 THEN cast(YEAR(MyDate) - 0 as char(4)) + '-Q2'
WHEN MONTH(MyDate) BETWEEN 10 AND 12 THEN cast(YEAR(MyDate) - 0 as char(4)) + '-Q3'
END FYrQtr
(but note the use of the cast() function: the concat() does implicit conversion from int to char types, while the + operator requires that the left part and the right part are char types)

How to split everything after - (dash) using MySQL

I need to split data within a cell separated by - (dash) and put into separate columns. The problem I am having is there may be more than one -.
So using the table below with the original data coming from sic_orig, I need to put everything before the first - in sic_num and everything after the first - in sic_desc. I'm sure this is really easy, but I can't seem to find anything clear on this.
This is what my table should look like with sic_orig being the source and sic_num and sic_desc being data pulled from sic_orig:
sic_orig | sic_num | sic_desc
---------------------------------------------------------------------------
509406 - Jewelers-Wholesale | 509406 | Jewelers-Wholesale
--------------------------------------|-----------|------------------------
506324 - Burglar Alarm Systems | 506324 | Burglar Alarm Systems
--------------------------------------|-----------|------------------------
502317 - Picture Frames-Wholesale | 502317 | Picture Frames-Wholesale
This code works, but only works right if there are two -'s and some cells may have 1, 2 or 3 -'s
UPDATE test_tbl_1
SET sic_num = SUBSTRING_INDEX(`sic_orig`, '-', 1),
sic_desc = SUBSTRING_INDEX(`sic_orig`, '-', -2);
How do I split everything before first - and everything after first -?
One method is to use the length of the first part and use that for substr():
UPDATE test_tbl_1
SET sic_num = SUBSTRING_INDEX(`sic_og`, '-', 1),
sic_desc = SUBSTR(sig_og, CHAR_LENGTH(SUBSTRING_INDEX(`sic_og`, '-', 1)) + 1) ;
You can use a combination of SUBSTR() and LOCATE() function to help you slice the string:
UPDATE test_tbl_1
SET sic_num = SUBSTR(sig_orig, 1, LOCATE('-', sig_orig) - 1),
sic_desc = SUBSTR(sig_orig, LOCATE('-', sig_orig) + 1) ;
Click here for MySQL string functions.
Another alternative is to get a count of the dashes in the string. We can get a count of the number of dash characters by doing a replacement of all dash characters with an empty string, and then subtracting the length from the length of the original string.
As a demonstration:
SELECT `sic_orig`
, CHAR_LENGTH(`sic_orig`)-CHAR_LENGTH(REPLACE(`sic_orig`,'-','')) AS cnt_dashes
FROM ( SELECT '509406 - Jewelers-Wholesale ' AS sic_orig
UNION ALL SELECT '506324 - Burglar Alarm Systems'
UNION ALL SELECT '502317 - Picture Frames-Wholesale'
UNION ALL SELECT ' la di dah no dashes '
) t
returns:
sic_orig cnt_dashes
------------------------------------- ----------
509406 - Jewelers-Wholesale 2
506324 - Burglar Alarm Systems 1
502317 - Picture Frames-Wholesale 2
lots-of - -dashes- --everywhere-- -- 10
zero dashes 0
We can use the expression that returns the count of dashes as the third argument of SUBSTRING_INDEX, multiplying by negative 1 to get a a negative value...
SELECT `sic_orig`
, TRIM(
SUBSTRING_INDEX(`sic_orig`,'-'
, 1
)
) AS before_first_dash
, TRIM(
SUBSTRING_INDEX(`sic_orig`,'-'
, -1*(CHAR_LENGTH(`sic_orig`)-CHAR_LENGTH(REPLACE(`sic_orig`,'-','')))
)
) AS after_first_dash
FROM ( SELECT '509406 - Jewelers-Wholesale ' AS sic_orig
UNION ALL SELECT '506324 - Burglar Alarm Systems'
UNION ALL SELECT '502317 - Picture Frames-Wholesale'
UNION ALL SELECT 'lots-of - -dashes- - -every-where-'
UNION ALL SELECT ' zero dashes '
) t
returns:
sic_orig before_first_dash after_first_dash
--------------------------------- ----------------- ----------------------
509406 - Jewelers-Wholesale 509406 Jewelers-Wholesale
506324 - Burglar Alarm Systems 506324 Burglar Alarm Systems
502317 - Picture Frames-Wholesale 502317 Picture Frames-Wholesale
lots-of - -dashes- - -every-where- lots of - -dashes- - -every-where-
zero dashes zero dashes
The extra line breaks and formatting is intended to make deciphering the expressions easier, making sure parens balance, etc.
I always test my expressions with a SELECT statement first, before I put those expressions into an UPDATE statement.

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

Getting a numeric value out of a string

In a table named TRY I have a column ABC which has records with value abc:30|def:g h i|j:k|l:m|n:o|p: |q: 0.25 |r:0.47|s:t u
I want to fetch the numeric value after r: The example given has value as r:0.47 But it can also have a value as 123456.012596363
I am not sure on using patindex. Can anyone please help.
Many Thanks
Try this...........
declare #abc nvarchar(100) = 'abc:30|def:g h i|j:k|l:m|n:o|p: |q: 0.25 |r:0.47|s:t u'
select
substring(substring(#abc,charindex('r:',#abc) + 2 ,len(#abc)),
1,
charindex('|',substring(#abc,charindex('r:',#abc) + 2,len(#abc))) - 1)
use this query for your table
select
substring(substring(abc,charindex('r:',abc) + 2 ,len(abc)),
1,
charindex('|',substring(abc,charindex('r:',abc) + 2,len(abc))) - 1)
from TRY
-----Final Try
select case when charindex('r:',abc) = 0 then abc else
substring(substring(abc,charindex('r:',abc) + 2 ,len(abc)),
1,
charindex('|',substring(abc,charindex('r:',abc) + 2,len(abc))) - 1) end
from TRY