i have a dataset in SQL server which has a column i wish to parse out.
Looking to get positive and negative values onto different columns and also if there is a multiplier to put in different column against the value it is to be multiplied against.
EG of how the column looks that i want to parse out
create table #temped (
originalstring varchar(100)
)
insert into #temped
select 'SUM([S720]) - SUM([S719]) * 2 + SUM([S719])'
insert into #temped
select 'SUM([R382]) + SUM([R989])'
insert into #temped
select 'SUM([S716]) * .295'
I would like to put the positive values in one column, the negative in another and the multiplier in another. the multiplier should be on the same row as the one it is to be multiplied against.
Example output of the first insert above would be
Col_positive Col_Neg Multiplier
S720 S719 2
S719
So far i've tried charindex and split string with also doublesplit which i found here: TSQL: Nested split/parse of string into table (multiple concatenated Tag:Value in one string)
Related
I have a column to check if contains number from 0-9 and a decimal. Since in the version of SQL am using the below does not seem working
select *
from tablename
whwere columnname like '%[^.0-9]%'
Also tried using column name like '%[0-9]%' and columnname not like '%.%' but if there is a negative sign it is not getting captured. Please advise.
The column data type is float. So can someone provide me a query to check if the column contains values from 0-9 and also it can contain decimal values these two are permitted. If say for example if I have value 9,9.99 ,-1.24 the query should output -1.24 I need this value other than decimal and number –
The issue with your LIKE clause is bad predicate logic ...like '%[^.0-9]%'should be NOT LIKE '%[^0-9.]%'
Take this sample data.
DECLARE #table TABLE (SomeNbr VARCHAR(32));
INSERT #table VALUES ('x'),('0'),('0.12'),('999'),('-29.33'),('88.33.22'),('9-9-'),('11-');
What you were trying to do would be accomplished like this:
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.]%';
The problem here is we'll also return "88.33.22" and miss "-29.33", both valid float values. You can handle hyphens by adding a hyphen to your LIKE pattern:
SELECT t.someNbr, LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.',''))
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%';
But now we also pick up "9-9-" and stuff with 2+ dots. To ensure that each starts with a number OR a hyphen, to ensure hyphens only exist in the front of the string (if at all) and that we a maximum of one dot:
--==== This will do a good job but can still be broken
SELECT t.someNbr
FROM #table AS t
WHERE someNbr NOT LIKE '%[^0-9.-]%' -- Can only contain numbers, dots and hyphens
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'.','')) < 2 -- can have up to 1 dot
AND LEN(t.SomeNbr)-LEN(REPLACE(t.SomeNbr,'-','')) < 2 -- can have up to 1 hyphen
AND PATINDEX('%-%',t.SomeNbr) < 2 -- hyphen can only be in the front
This does the trick and returns:
someNbr
--------------------------------
0
0.12
999
-29.33
All that said - **DONT DO THIS ANY OF THIS ^^^ **. There is no need to parse numbers in this way except to show others why not to. I can still break this. They way I return valid floats in a scenario like this is with TRY_CAST or TRY_CONVERT. This returns what you need and will perform better.
--==== Best Solution
SELECT t.someNbr
FROM #table AS t
WHERE TRY_CAST(t.SomeNbr AS float) IS NOT NULL;
Hopefully everyone is having a productive lockdown all over the world. This is my second issue I wanted some assistance with today.
What I have is a chat from a telecom company signing up new customers.
I have successfully collapsed them into 2x rows per unique_id - a unique chat interaction captured between customer and company agent.
I would like to now take each column (text) in each row and separate
it out to 5 equal varchar columns.
The objective is to splice/chunk a
conversation into 5 different stages within this table.
I do not
have access to delimiters as customers and company staff use
delimiting characters themselves so it makes this tricky.
Below I have 2 images with what the data looks like now and what I am looking for.
BEFORE
AFTER
I have looked at the following articles to try to crack it, but am stuck:
Split A Single Field Value Into Multiple Fixed-Length Column Values in T-SQL
How to Split String by Character into Separate Columns in SQL Server
How to split a comma-separated value to columns
How to split a single column values to multiple column values?
Split string in SQL Server to a maximum length, returning each as a row
Here is the SQL Fiddle page, but I am running this code in MS SQL Server: http://sqlfiddle.com/#!9/ddd08c
Here is the table creation code:
CREATE TABLE Table1
(`unique_id` double, `user` varchar(8), `text` varchar(144))
;
INSERT INTO Table1
(`unique_id`, `user`, `text`)
VALUES
(50314585222, 'customer', 'This is part 1 of long text. This is part 2 of long text. This is part 3 of long text. This is part 4 of long text. This is part 5 of long text.'),
(50314585222, 'company', 'This is part 1 of long text This is part 2 of long text This is part 3 of long text This is part 4 of long text This is part 5 of long text'),
(50319875222, 'customer', 'This is part 1 This is part 2 This is part 3 This is part 4 This is part 5'),
(50319875222, 'company', 'This is part 1 This is part 2 This is part 3 This is part 4 This is part 5')
;
I have requested an almost similar algorithm in R, in my history. I have been trying to do this in SQL.
I have manage to solve this with the T-SQL statement below:
WITH DataSource AS
(
SELECT *
,'\b.{1,'+CAST(CEILING(LEN([text]) * 1.0 /5) AS VARCHAR(12)) +'}\b' AS [pattern]
FROM TAble1
), PreparedData AS
(
SELECT unique_id
,[user]
,'text' + CAST(RM.matchID + 1 AS VARCHAR(12)) as [column]
,RM.CaptureValue AS [value]
FROM DataSource T
CROSS APPLY [dbo].[fn_Utils_RegexMatches] ([text], [pattern]) RM
)
SELECT *
FROM PreparedData DS
PIVOT
(
max([value]) for [column] IN ([text1], [text2], [text3], [text4], [text5])
) PVT;
In order to use this code, you need to implement SQL CLR function(s) for working with regular expression in the context of T-SQL (you need to invest some time understanding how SQL CLR works) - otherwise, you will not be able to use this solution.
So, having RegexMatches function, the first part is to build a regular expression pattern for splitting the data:
SELECT *
,'\b.{1,'+CAST(CEILING(LEN([text]) * 1.0 /5) AS VARCHAR(12)) +'}\b' AS [pattern]
FROM TAble1;
The pattern is \b.number\b and will match part of the strings with length number but not cutting the words (check if boundary works for you, because in some cases it won't).
Then, using our regex matches function we getting a result like this (the second common table expression):
And the data above is ready for pivoting which is pretty easy.
So, the notes are:
you need to implement Microsoft String Utility
you need to ensure the regex pattern works for you
you can split the T-SQL I used, check the other columns of the regex function and even make dynamic pivoting - the code is an example and need to modify/check it before using in production
I am trying to write a SQL query that only returns rows where a specific column (let's say 'amount' column) contains numbers comprising of only one digit, e.g. only '1's (1111111...) or only '2's (2222222...), etc.
In addition, 'amount' column contains numbers with decimal points as well and these kind of values should also be returned, e.g. 1111.11, 2222.22, etc
If you want to make the query generic that you don't have to specify each possible digit you could change the where to the following:
WHERE LEN(REPLACE(REPLACE(amount,LEFT(amount,1),''),'.','') = 0
This will always use the first digit as comparison for the rest of the string
If you are using SQL Server, then you can try this script:
SELECT *
FROM (
SELECT CAST(amount AS VARCHAR(30)) AS amount
FROM TableName
)t
WHERE LEN(REPLACE(REPLACE(amount,'1',''),'.','') = 0 OR
LEN(REPLACE(REPLACE(amount,'2',''),'.','') = 0
I tried like this in place of 1111111 replace with column name:
Select replace(Str(1111111, 12, 2),0,left(11111,1))
I have a pretty hard request to do in SQL Server 2008, but I'm not able to do the whole...
I have two kind of records :
16HENFC******** (8 numbers after more 'FC')
16HEN******* (7 numbers after more 'EN')
I have to select the * (which are in fact numbers), and add a 0 at the beginning of the second form of record to just have 8 long selected values.
Then I have to insert the result in a empty table.
I think I did the first part which is :
SUBSTRING(SELECT mycolumn1 FROM mytable1 WHERE mycolumn1 LIKE '16HENFC%', 5, 8) ;
In summary,
I have those records in my column :
'16HENFC071052'
'16HEN5130026'
I want to select them and transform them to insert those ones in an other column :
'05130026'
'FC071052'
[EDIT]=>
CREATE TABLE nom_de_la_table
(
colonne1 VARCHAR(250),
colonne2 VARCHAR(250)
)
INSERT INTO nom_de_la_table (colonne1)
VALUES
('16HEN5138745'),
('16HENFC071052v2'),
('16HENFC78942878'),
('16HEN4830026'),
('16HEN7815934'),
('16HENFC74859422'),
('16HEN9687326'),
('16HENFC74889639'),
('16HEN9798556');
[etc...]
So two different types of records, and I want to insert the result of what you did first with just two records in an other column but for the 956 records of my table. And this is the result with the two examples :
'05130026'
'FC071052'
Left-Filling a string is a relatively easy request. Here's an example:
select right(replicate('0',8) + right(test,len(test)-len('16HEN')),8)
from (
select '16HENFC071052' as test
union all
select '16HEN5130026' as test
) z
Use replicate to left-fill your string with the amount of digits you wish to end up with. Append your desired string, in this case, slice your prefix off by taking the right X characters where X = len(target) - len(prefix). Finally, take the right characters of the whole string equal to your desired length.
I have column OFF_SAT_COMP.LINKACCT and OFF_SAT_COMP.COUNTRY. I am trying to add the values of these two columns in a given row together, but when I do so as follows:
(OFF_SAT_COMP.LINKACCT + OFF_SAT_COMP.COUNTRY)
It is concatenating rather than returning the sum of the two column values. e.g. It is returning 500300 where I want 800. How can I force it to use addition and not read the sign as concatenation? I'm guessing its auto-flipping to concatenation b/c one of the columns is returning as a string rather than an integer - but they are both truly integers (yes, this database is screwed up - no, I can't fix it...legacy/third-party).
You simply need to cast the non-integer values
(Cast(OFF_SAT_COMP.LINKACCT As int) + Cast(OFF_SAT_COMP.COUNTRY As int)
Dave,
Cast one of the columns to integer
Select column1 + cast(column2 as integer)
from table