SQL Server : Reuse calculated variable in select clause - sql

I have the following table structure:
col1 col2 col3 col4
-------------------------------
aK Mbcd ABc defgh
col2, col3 and col4 columns are of type varchar(100) and col1 has type varchar(500).
I need a select query to have the output as following
col1 col2 col3 col4
-------------------------------
aK,Mb cd,A Bc,d efgh
Logic is explained as mentioned below:
In the result, Col2, col3 and col4 can have maximum 4 characters but col1 can have more than 4 characters upto 100.
If any column has more characters, last 4 characters will be retained in the same column and other extra columns will be concatenated with previous column's value separated by comma , and the same rule will be applied on the concatenated values as well.
I've written the following T-SQL statement. It works fine for last two columns. But I want to use new calculated value of col3 to strip out extra characters after adding some from col4
SELECT
CASE
WHEN X.Col4Length > 4
THEN concat(X.col3, ',', substring(x.col4, 0, X.Col4Length - 3))
ELSE X.col3
END AS col3,
CASE
WHEN X.Col4Length > 4
THEN substring(x.col4, X.Col4Length - 3, x.Col4Length)
ELSE X.col4
END AS col4
FROM
(SELECT
Col1, Col2, Col3, Col4,
Len(Col1) AS Col1Length,
Len(Col2) AS Col2Length,
Len(Col3) AS Col3Length,
Len(Col4) AS Col4Length
FROM
mytable) X

My try with a simple sub-query
with t1 as (
select 'aK' col1, 'Mbcd' col2, 'ABc' col3, 'defgh' col4
---
SELECT LEFT(col, LEN(col) - 12) col1,
RIGHT(LEFT(col, LEN(col) - 8), 4) col2,
RIGHT(LEFT(col, LEN(col) - 4), 4) col3,
RIGHT(col, 4) AS col4
FROM
(
SELECT col1+','+col2+','+col3+','+col4 AS col
FROM t1
) t;

You want to reuse calculated variables
There are two set-based /inline / adhoc approaches (and many more ugly procedural):
CTEs to do this for the whole set in advance
CROSS APPLY for the same on row level
Try it like this (CTE approach)
DECLARE #tbl TABLE(col1 VARCHAR(100),col2 VARCHAR(100),col3 VARCHAR(100),col4 VARCHAR(100));
INSERT INTO #tbl VALUES
('aK','Mbcd','ABc','defgh')
,('123456','abc','3456','123456789');
WITH ResolveCol4 AS
(
SELECT *
,RIGHT(col4,4) AS Col4_resolved
,col3 + ',' + CASE WHEN LEN(col4)>4 THEN SUBSTRING(col4,1,LEN(col4)-4) ELSE '' END AS col3_New
FROM #tbl
)
,ResolveCol3 AS
(
SELECT *
,RIGHT(col3_New,4) AS Col3_resolved
,col2 + ',' + CASE WHEN LEN(col3_New)>4 THEN SUBSTRING(col3_New,1,LEN(col3_New)-4) ELSE '' END AS col2_New
FROM ResolveCol4
)
,ResolveCol2 AS
(
SELECT *
,RIGHT(col2_New,4) AS Col2_resolved
,col1 + ',' + CASE WHEN LEN(col2_New)>4 THEN SUBSTRING(col2_New,1,LEN(col2_New)-4) ELSE '' END AS col1_New
FROM ResolveCol3
)
SELECT col1_new,Col2_resolved,Col3_resolved,Col4_resolved
FROM ResolveCol2
The result
aK,Mb cd,A Bc,d efgh
123456,abc,34 56,1 2345 6789

Related

How to insert character in between a string in SQL

I have a col1 in tbl1 which has data as under:
C:\ABC\1245_PQR\125\xyz\ROW20MAOSAD12\
now I want to insert a '\' after C:\ABC\1245_PQR\125\xyz\ROW and before '20MAOSAD12\'
and the data format is same but it changes in all row, for example -
C:\ABC\1245_PQR\125\xyz\ROW20MAOSAD12\
C:\ABC\3456_ADR\515\xpo\ROWadMAOSAD23\
C:\ABC\1547_DFR\255\RDS\ROW14SDFS15\
Can someone please help.
Thanks
You can use replace function
SELECT REPLACE('C:\ABC\1245_PQR\125\xyz\ROW20MAOSAD12\', '\ROW', '\ROW\')
To be more precise
SELECT REPLACE(col1, '\ROW', '\ROW\') from tbl1
Alternatively you could consider the STUFF operator:
STUFF ( character_expression , start , length , replaceWith_expression )
SELECT STUFF('C:\ABC\1245_PQR\125\xyz\ROW20MAOSAD12\',28,0, '\')
SELECT STUFF('SomeColumn',28,0, '\') FROM SomeTable WHERE SomeColumn=SomeValue
Also, I made this one - a bit lengthy
-- Step 1
Select all rows that have ...xyz.... in col1 and col2 is xyz
select * from tbl where col2 = 'row' and col1 like '%xyz%'
-- Step 2
-- From the rows above, calculate the start index of ...xyz....... in col1
select charindex('xyz', col1) from (select col1 from tbl where col2 = 'xyz' and col1 like '%xyz%') tmp
-- Step 3
-- Split the col1 from CharIndex + 3 (size of xyz)
select left(col1, charindex('xyz', col1) + 2 ), substring(col1, charindex('xyz', col1) + 3, LEN(col1) ), ( left(col1, charindex('xyz', col1) + 2 ) + '\' + substring(col1, charindex('xyz', col1) + 3, LEN(col1) ))
from (select col1 from tbl where name = 'xyz' and col1 like '%xyz%') tmp
-- Step 4
-- Update !!
update tbl
SET col1 = ( left(col1, charindex('xyz', col1) + 2 ) + '\' + substring(col1, charindex('xyz', col1) + 3, LEN(col1) ))
where col2 = 'xyz' and col1 like '%xyz%' and col1 not like '%xyz\%'

Combine columns from three different tables into a single column

I am new to SQL and I am not sure what to Google. I have three tables with different numbers of columns. I would like to combine these following three tables into a single column(no duplicates).
Table1
Col1 Col2 Col3
1 a aa
2 b ab
3 c bb
Table2
Col1 Col2
123 Test
456 Test2
346 Test3
Table3
Col1 Col2 Col3 Col4
5695 93234 ABC CDE
4534 92349 MSF KSK
3244 12323 SLE SNE
Expected Output:
FileOutput
1aaa
123Test
569593234ABCCDE
2bab
456Test2
453492349MSFKSK
...
Any help would be much appreciated. Thanks!
The term you would want to Google would be: UNION and CONCAT.
Note: CONCAT is not supported in prior versions to SQL Server 2012.
To get your expected output, I would do this:
select
concat(cast(col1 as varchar(10)),col2,col3) as FileOutput
from table1
UNION
select
concat(cast(col1 as varchar(10)),col2) as FileOutput
from table2
UNION
select
concat(cast(col1 as varchar(10)),cast(col2 as varchar(10)),col3,col4) as FileOutput
from table3
SQL Fiddle Demo
Not sure how you would parse the data, but you could do this:
select convert(varchar(100), col1) + convert(varchar(100), col2) + convert(varchar(100), col3) as fileOutput
from table1
union all
select convert(varchar(100), col1) + convert(varchar(100), col2) as fileOutput
from table2
union all
select convert(varchar(100), col1) + convert(varchar(100), col2) +
convert(varchar(100), col3) + convert(varchar(100), col4) as fileOutput
from table4
note not knowing your column data types, your varchar(100) may need to expand, or could potentially shrink depending on your data.
You can combine them using + (may need to cast your ints as varchars for this to work), then put them all in one table using union all. Example:
Select cast(col1 as varchar(100)) + col2 + col3
from Table1
union all
select cast(col1 as varchar(100)) + col2
from Table2
etc.
Note: be sure to use union all rather than union if you want to keep any duplicates you may create.

Substring sql query

The following query would return
PR-2014-00006-02
Query:
select PRItemNo
from tPRItem
order by PRItemNo ASC
I want to sub string such as I will return the following result
col1 col2 col3 col4
PR 2014 00006 02
Use PARSENAME
--Using PARSENAME
SELECT PARSENAME(REPLACE(PRItemNo ,'-','.'),4) col1,
PARSENAME(REPLACE(PRItemNo ,'-','.'),3) col2,
PARSENAME(REPLACE(PRItemNo ,'-','.'),2) col3,
PARSENAME(REPLACE(PRItemNo ,'-','.'),1) col4
FROM Table1
Fiddle Demo
Output
COL1 COL2 COL3 COL4
PR 2014 00006 02
declare #t VARCHAR(30)= 'PR-2014-00006-02'
SELECT SUBSTRING(#t,CHARINDEX(#t,'-'),3),
SUBSTRING(substring(#t, charindex('-',#t) + 1,len(#t) - charindex('-',#t)),0,CHARINDEX('-',#t)+2),
RIGHT(substring(#t, charindex('-',#t) + 1,len(#t) - charindex('-',REVERSE(#t))-CHARINDEX('-',#t)),5),
REVERSE(LEFT(reverse(#t), charindex('-', reverse(#t)) - 1))

Complex summing in SQL

I'm working with a relational database that uses SQL99.
I have a series of 10 columns, each of the 10 columns contain a number value.
I need to sum each column individually and then take those sums and add them all together to get an overall sum. Then I must divide the overall sum by 15.
I've tried every format I can think of and have yet to return any results. I have no idea what the syntax should look like.
SELECT SUM(col1), SUM(col2)..., SUM(col1 + col2 + col3 + col4...)/15
FROM TABLENAME
GROUP BY 1=1
select
sum(col1) as sum1,
sum(col2) as sum2,
sum(col3) as sum3,
sum(col4) as sum4,
sum(col5) as sum5,
sum(col6) as sum6,
sum(col7) as sum7,
sum(col8) as sum8,
sum(col9) as sum9,
sum(col10) as as sum10,
sum( col1 + col2 + col3 + col4 + col5 + col6 + col7 + col8 + col9 + col10) as overallsum,
sum( col1 + col2 + col3 + col4 + col5 + col6 + col7 + col8 + col9 + col10) / 15 as dividedsum
from
tablename
SELECT SUM(subsum) / 15 FROM (
SELECT SUM(column1) AS subsum
FROM table
UNION ALL
SELECT SUM(column2) AS subsum
FROM table
UNION ALL
...
SELECT SUM(column10) AS subsum
FROM table
)

SQL Server: select value, split on a delimiter, then update two columns

I have a SQL Server 2008 database table with three varchar Columns - Col1, Col2, Col3. Col1 has data in it with a single space in between, Col2 and Col3 are empty.
I need to write a query to select the data from Col1, break up each value using the space as the delimiter, and inserting the data on either side of the space into Col2 and Col3 respectively.
I am not too sure how to proceed. Can this be accomplished in SQL, or should I create a small program to do the work for me? I'd appreciate a pointer in the right direction if this can be accomplished via SQL.
Thanks.
UPDATE table SET
Col2 = SUBSTRING(Col1, 1, CHARINDEX(' ', Col1)-1),
Col3 = SUBSTRING(Col1, CHARINDEX(' ', Col1)+1, 8000)
WHERE Col1 LIKE '% %';
If you can guarantee there is only one space:
create table #temp (col1 varchar(50),col2 varchar(50), col3 varchar(50))
insert into #temp (col1)
select 'test 1'
union all
select 'test 2'
union all
select 'test 3'
update #temp
set col2 = left(col1, charindex (' ', col1)),
col3 = substring(col1,charindex (' ', col1)+1, len(col1))
from #temp