1

I'm trying to pass column names using a string split because I need the values from that table to join with another table.

I've already achieved this in Postgresql where I get the values from these columns:

 SELECT unnest(array["column_name1","column_name2","column_name3" AS "amount"
 FROM table1

The unnest in combination with the quotes around the column names returns an array to a set of row for every value.

Amount
307579.00
25579.00
212871.00

Now I want to do the same in MS Server:

 DECLARE @amount NVARCHAR(50) = 'column_name1/column_name2/column_name3'
 SELECT "value" from string_split(@amount,'/')

But this only gives me the literal string:

Amount
column_name1
column_name2
column_name3

I've been trying and searching how to pass an elemant that will read as a column name and shows the values in one column like the first example, maybe I shouldn't use the string splitter etc. Kinda stuck on this..

asked Dec 27, 2018 at 13:58
4
  • For those of us unfamiliar with Postgresql what does the unnest(array do? Can you provide example data and desired results? Commented Dec 27, 2018 at 14:15
  • string_split starts at SqlServer 2016, you should use some function like stackoverflow.com/a/10914602/3270427. Commented Dec 27, 2018 at 14:19
  • Yes, so I thought, but I've been using string_split in SqlServer 2014 and works just fine when I actually need the literal string. Commented Dec 27, 2018 at 14:26
  • Then someone has added a function with this name. Commented Dec 27, 2018 at 14:31

2 Answers 2

3

You'll need to use dynamic SQL to implement your logic, by constructing a whole new SELECT query.

For example:

DECLARE @CMD nvarchar(max), @amount NVARCHAR(50) = 'column_name1/column_name2/column_name3'
SELECT @CMD = ISNULL(@CMD + ', ', N'SELECT ') + QUOTENAME([value])
FROM STRING_SPLIT(@amount,'/')
SET @CMD = @CMD + N' FROM table1'
PRINT @CMD
EXEC(@CMD)

Its output would be:

SELECT [column_name1], [column_name2], [column_name3] FROM table1

In order to get all the values under a single column, you'll need to "UnPivot" the data. There are two main ways to do so. One is by a standard UNPIVOT command, like so:

DECLARE @CMD nvarchar(max), @amount NVARCHAR(50) = 'column_name1/column_name2/column_name3'
SELECT @CMD = ISNULL(@CMD + ', ', N'SELECT unpvt.* FROM table1 UNPIVOT (amount FOR amounttype IN ( ') + QUOTENAME([value])
FROM STRING_SPLIT(@amount,'/')
SET @CMD = @CMD + N' ) AS unpvt'
PRINT @CMD
EXEC(@CMD)

Its output would be:

SELECT unpvt.* FROM table1 UNPIVOT (amount FOR amounttype IN ( [column_name1], [column_name2], [column_name3]) AS unpvt

Another way is to use CROSS APPLY with a Values Constructor, like this:

DECLARE @CMD nvarchar(max), @amount NVARCHAR(50) = 'column_name1/column_name2/column_name3'
SELECT @CMD = ISNULL(@CMD + '), (', N'SELECT v.amount FROM table1 CROSS APPLY(VALUES(') + QUOTENAME([value])
FROM STRING_SPLIT(@amount,'/')
SET @CMD = @CMD + N')) AS v(amount)'
PRINT @CMD
EXEC(@CMD)

Its output would be:

SELECT v.amount FROM table1 CROSS APPLY(VALUES([column_name1]), ([column_name2]), ([column_name3])) AS v(amount)
answered Dec 27, 2018 at 14:30
4
  • This actually gives me the values, but in separate columns. Is it possible to have one column e.g. 'amount' with the values stored there? Commented Dec 28, 2018 at 9:44
  • Seems I misunderstood your requirements. Sure, I'll edit my answer accordingly. Commented Dec 29, 2018 at 3:57
  • 1
    I used the CROSS APPLY and got my desired result. Thanks! Commented Jan 2, 2019 at 14:10
  • Pleasure @MarG :) Commented Jan 3, 2019 at 15:49
0
create table t (id int, mytext varchar(500));
insert into t values (1, 'column_name1/column_name2/column_name3');
select id, value as amount
from t
cross apply STRING_SPLIT(mytext, '/');
id | amount 
-: | :-----------
 1 | column_name1
 1 | column_name2
 1 | column_name3

db<>fiddle here

answered Dec 27, 2018 at 15:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.