Join of 2 Set Exec Strings in TSQL - tsql

I have 2 select statements inside of strings setup like this:
set #sql = 'Select.......' -- (Returns col1, col2, col3)
exec (#sql)
set #sql = 'Select.......' -- (Returns col4, col5, col6)
exec (#sql)
I want to Join these 2 exec statements so that the columns will appear like this as a result:
col1 | col2 | col3 | col4 | col5 | col6
Any tips? Thanks.

Turn on DATA ACCESS on your local server:
exec sp_serveroption #server = 'YourServerName'
,#optname = 'DATA ACCESS'
,#optvalue = 'TRUE'
And use OPENQUERY:
select
*
from (
select * from openquery(YourServerName, 'select 1 as a')
) t1
full join (
select * from openquery(YourServerName, 'select 3 as b')
) t2
on t1.a = t2.b

DECLARE #SQL1 VARCHAR(MAX)
DECLARE #SQL2 VARCHAR(MAX)
SET #SQL1='SELECT COL1,COL2,NULL AS COL3,NULL AS COL4 FROM #TEST1'
SET #SQL2='SELECT NULL,NULL, COL3, COL4 FROM #TEST2'
EXEC (#SQL1 +' UNION ALL '+ #SQL2)

I got the result that I wanted by removing the EXEC and keeping them as plain Select statements. Then I performed an Inner Join to avoid NULLS. Thanks all for the help.

Related

Incorrect syntax near the keyword 'IF', IF after WITH

I am trying to make an IF after a WITH and it is giving me the error Incorrect syntax near the keyword 'IF'
below an example of the stored procedure I am writing
CREATE PROCEDURE [dbo].[Proc_MyProc]
#MODE INT = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
WITH ss as (
select col1, col2, col3, col4, col5
from TableTest
)
IF #MODE = 1
select col1 as A, col2, sum(col5) as col5sum
from ss
group by col1, col2
order by col5sum desc
ELSE IF #MODE = 2
select col1, col2, sum(col5) as col5sum
from ss
group by col1, col2, col3
order by col5sum desc
ELSE IF #MODE = 3
select col1, col2, sum(col5) as col5sum
from ss
group by col1, col2, col4
order by col5sum desc
END
GO
I tried to remove the WITH and the syntax error gone, but off course it is not a solution
Thanks :)
The WITH goes with the SELECT, so you need to repeat the WITH or use a temporary table.
In this case, though, the WITH really has no value -- let me assume that it is simplified.
The first method would be:
if #MODE = 1
with ss as (
select col1, col2, col3, col4, col5
from TableTest
)
select col1 as A, col2, sum(col5) as col3sum
from #ss
group by col1, col2
having SnQuantity > 0
order by availability desc;
. . .
The second method would be:
select col1, col2, col3, col4, col5
into #ss
from TableTest;
if #MODE = 1
select col1 as A, col2, sum(col5) as col3sum
from #ss
group by col1, col2
having SnQuantity > 0
order by availability desc;
. . .

Concatenating NULL returns a value in T-SQL (CONCAT function)

Why does this return . when col1 contains a blank value?
CONCAT(NULLIF([COL1],''),'.')
I have 3 columns that i need to concatenate with a . in between, sometimes the column contains a blank value. In that case the trailing . should not be concatenated. What functions do I use?
col1 col2 col3
A 1 x
B 2
expected results:
A.1.X
B.2
test code:
DECLARE #tbl TABLE(a varchar(100),b varchar(100),c varchar(100))
INSERT INTO #tbl
SELECT 'A','1','X' UNION
SELECT 'B','2','' UNION
SELECT 'C','','' UNION
SELECT '','1','X' UNION
SELECT 'B','','' UNION
SELECT 'C','',''
SELECT CONCAT ( Nullif(a,''),'.' + nullif(b,''), '.' + nullif(c,'')) AS Contact_Result FROM #tbl;
You can use SQL CONCAT this way
SELECT CONCAT ( a,IIF((NULLIF(a,'')+NULLIF(b,'')) IS NULL,'','.'),b,IIF((NULLIF(b,'')+NULLIF(c,'')) IS NULL,'','.'), c) AS Contact_Result FROM #tbl;
Test code below
DECLARE #tbl TABLE(a varchar(100),b varchar(100),c varchar(100))
INSERT INTO #tbl
SELECT 'A','1','X' UNION
SELECT 'B','2',NULL UNION
SELECT 'C',NULL,NULL
SELECT CONCAT ( a,IIF((NULLIF(a,'')+NULLIF(b,'')) IS NULL,'','.'),b,IIF((NULLIF(b,'')+NULLIF(c,'')) IS NULL,'','.'), c) AS Contact_Result FROM #tbl;
Contact_Result
A.1.X
B.2
C
Another common use of this kind of concats is to Concat a Full Name in this case the . (dot) is replaced by a ' ' (space), it makes things easier because you can use trim
DECLARE #tbl TABLE(a varchar(100),b varchar(100),c varchar(100))
INSERT INTO #tbl
SELECT 'FirtName','MiddleName','LastName' UNION
SELECT 'FistName','','LastName' UNION
SELECT '','','FullName'
SELECT LTRIM(CONCAT ( a,' ' + b,' ' + c)) AS Contact_Result FROM #tbl;
Result
FullName
FirtName MiddleName LastName
FistName LastName
THIS IS AN ANSWER THAT COVERS ALL POSSIBILITIES
SELECT SUBSTRING(CONCAT ('.' + NULLIF(a,''),'.' + NULLIF(b,''),'.' + NULLIF(c,'')),2,10000) AS Contact_Result FROM #tbl;
Complete test cases
DECLARE #tbl TABLE(a varchar(100),b varchar(100),c varchar(100))
INSERT INTO #tbl
SELECT 'a','','' UNION
SELECT 'a','b','' UNION
SELECT 'a','b','c' UNION
SELECT 'a','','c' UNION
SELECT '','b','c' UNION
SELECT '','b','' UNION
SELECT '','','c' UNION
SELECT '','',''
SELECT SUBSTRING(CONCAT ('.' + NULLIF(a,''),'.' + NULLIF(b,''),'.' + NULLIF(c,'')),2,10000) AS Contact_Result FROM #tbl;
Results
c
b
b.c
a
a.c
a.b
a.b.c
You'll have to go old school. I'm on my phone and can't test this.
ISNULL(NULLIF([COL1],'') + '.', '') +
ISNULL(NULLIF([COL2],'') + '.', '') +
ISNULL(NULLIF([COL3],''), '');
---------------- EDIT ----------------
Okay, this was not as easy on my phone as I thought. Here's my updated solution that works with SQL Server 2005+
-- sample data
declare #table table
(
id int identity,
col1 varchar(10),
col2 varchar(10),
col3 varchar(10)
);
insert #table (col1, col2, col3)
values ('a','b','c'), ('aa','bb',''), ('x','','z'), ('','p','pp'),
('!!!','',''), ('','','fff'), ('','','');
-- My solution
select col1, col2, col3, concatinatedValue =
case when cv like '.%' then stuff(cv, 1, 1,'') else cv end
from #table
cross apply (values
(isnull(nullif([col1],''), '') +
isnull('.'+nullif([col2],''), '') +
isnull('.'+nullif([col3],''), ''))) v(cv);
RETURNS
cv col1 col2 col3 concatinatedValue
--------- ----- ----- ----- -------------------
a.b.c a b c a.b.c
aa.bb aa bb aa.bb
x.z x z x.z
.p.pp p pp p.pp
!!! !!! !!!
.fff fff fff
<----------- blank line ----------->

SQL - How to roll up results into 1 row

If I have a table:
ID NAME
1 Red
2 Blue
3 Green
How can I return a query so that my result is:
Col1 Col2 Col3
Red Blue Green
Would I just do an inner join on itself or would I need a pivot table?
Yes, you can do it with join, eg:
select t1.name col1, t2.name col2, t3.name col3
from yourtable t1
join yourtable t2 on t2.id=2
join yourtable t3 on t3.id=3
where t1.id=1;
Or you can simply do it with embedded select statements, like:
In MySQL:
select
(select name from yourtable where id=1) col1,
(select name from yourtable where id=2) col2,
(select name from yourtable where id=3) col3;
In Oracle:
select
(select name from yourtable where id=1) col1,
(select name from yourtable where id=2) col2,
(select name from yourtable where id=3) col3
from dual;
Of course in that query the number of cols is fixed, you must edit it if you add more rows to roll up.
you can use dynamic SQL with PIVOT:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(id)
from yourtable
group by ColumnName, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select id, ColumnName
from yourtable
) x
pivot
(
max(ColumnName)
for id in (' + #cols + N')
) p '
exec sp_executesql #query;

How to filter sql duplicates?

My question: I want the records without duplicate, in the same table and in multiple tables? How can I proceed to do this in SQL?
Let me explain what I have tried:
Select distinct Col1, col2
from Table
where order id = 143
Output
VolumeAnswer1 AreaAnswer1 heightAnswer1
VolumeAnswer2 AreaAnswer1 heightAnswer2
VolumeAnswer3 AreaAnswer1 heightAnswer2
Expected Output
It shows the duplicate for the second table, but I need the output to be like:
VolumeAnswer1 AreaAnswer1 heightAnswer1
VolumeAnswer2 heightAnswer2
VolumeAnswer3
I need the same scenario for multiple tables, same duplicate I found for joins also. If it cannot be handled in SQL Server, how can we handle it in .Net? I used multiple select but they used to change it in single select. Each and every column should bind in dropdownlist...
Something like this might be a good place to start:
;with cte1 as (
Select col1, cnt1
From (
Select
col1
,row_number() over(Partition by col1 Order by col1) as cnt1
From tbltest) as tbl_sub1
Where cnt1 = 1
), cte2 as (
Select col2, cnt2
From (
Select
col2
,row_number() over(Partition by col2 Order by col2) as cnt2
From tbltest) as tbl_sub2
Where cnt2 = 1
), cte3 as (
Select col3, cnt3
From (
Select
col3
,row_number() over(Partition by col3 Order by col3) as cnt3
From tbltest) as tbl_sub3
Where cnt3 = 1
)
Select
col1, col2, col3
From cte1
full join cte2 on col1 = col2
full join cte3 on col1 = col3
Sql Fiddle showing example: http://sqlfiddle.com/#!3/c9127/1

SQL Server 2008 T-SQL UDF Split() Tailoring

I'm useing SQL Ser 2008 and have a large table with only one column of data. The data is a random string with very little consistency. Eample: Name Account 445566 0010020056893010445478008 AFD 369. I've been working with a split function that a stackoverflow user suggested. It works great but the function assigns the split string into one column. I need a row of individual columns. The present result is 1col with values Name, Account, 445566,... in it but the result I'm looking for is col1 Name, col2 Account, col3 445566,...
If anyone could provide some insight on how to tailor this script or its usage to get the desired result it would be much appreciated.
CREATE FUNCTION [dbo].[Split]
(
#String varchar(max)
,#Delimiter char
)
RETURNS #Results table
(
Ordinal int
,StringValue varchar(max)
)
as
begin
set #String = isnull(#String,'')
set #Delimiter = isnull(#Delimiter,'')
declare
#TempString varchar(max) = #String
,#Ordinal int = 0
,#CharIndex int = 0
set #CharIndex = charindex(#Delimiter, #TempString)
while #CharIndex != 0 begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,substring(#TempString, 0, #CharIndex)
)
set #TempString = substring(#TempString, #CharIndex + 1, len(#TempString) - #CharIndex)
set #CharIndex = charindex(#Delimiter, #TempString)
end
if #TempString != '' begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,#TempString
)
end
return
end
--The usage:
SELECT
*
FROM
mytable M
CROSS APPLY
[dbo].[Split] (M.TheColumn, ' ') S
Where rtrim(s.StringValue) != ''
If you know that you have 6 columns in the string you can use a split functions that looks like this and of course modify the function to whatever number of columns you want. A function can not return a dynamic number of columns.
create function dbo.Split6(#String varchar(max), #Delimiter char(1))
returns table as return
(
select
substring(T.Col, 1, S1.Pos-1) as Col1,
substring(T.Col, S1.Pos+1, S2.Pos-S1.Pos-1) as Col2,
substring(T.Col, S2.Pos+1, S3.Pos-S2.Pos-1) as Col3,
substring(T.Col, S3.Pos+1, S4.Pos-S3.Pos-1) as Col4,
substring(T.Col, S4.Pos+1, S5.Pos-S4.Pos-1) as Col5,
substring(T.Col, S5.Pos+1, S6.Pos-S5.Pos-1) as Col6
from (select #String+replicate(#Delimiter, 6)) as T(Col)
cross apply (select charindex(#Delimiter, T.Col, 1)) as S1(Pos)
cross apply (select charindex(#Delimiter, T.Col, S1.Pos+1)) as S2(Pos)
cross apply (select charindex(#Delimiter, T.Col, S2.Pos+1)) as S3(Pos)
cross apply (select charindex(#Delimiter, T.Col, S3.Pos+1)) as S4(Pos)
cross apply (select charindex(#Delimiter, T.Col, S4.Pos+1)) as S5(Pos)
cross apply (select charindex(#Delimiter, T.Col, S5.Pos+1)) as S6(Pos)
)
Test:
declare #T table (Col varchar(100))
insert into #T values
('Name Account 445566 0010020056893010445478008 AFD 369'),
(''),
('1 2'),
('1 3')
select S.Col1, S.Col2, S.Col3, S.Col4, S.Col5, S.Col6
from #T as T
cross apply
dbo.Split6(T.Col, ' ') as S
Result:
Col1 Col2 Col3 Col4 Col5 Col6
---- ------- ------ ------------------------- ---- ----
Name Account 445566 0010020056893010445478008 AFD 369
1 2
1 3
You might try using a PIVOT.
http://msdn.microsoft.com/en-us/library/ms177410.aspx