With IN Clause when Passing Collection as Parameter In Sql Server - sql

Query Gives O/p as
ItemSizeNM
(colName)
'U','V','X','Y'
But when I used this as input to IN Query in the Code Which I did.
It Doesn't Gives same resultset. Why This Happens...?
Table MstItemSize Has Proper Data.
declare #tblRingSize table ( ringSize varchar(100))
declare #ringSize varchar(100)
select #ringSize= cast((otherringSize) as varchar)
from ##tempBand where styleNo='BD00002';
INSERT INTO #tblRingSize SELECT Item FROM dbo.SplitStrings_CTE (#ringSize, ',');
select ItemSizeNm from MstItemSize where SizeTypeNm ='Ring' and
ItemSizeNm
in --('U','V','X','Y')
( select Replace (
(select STUFF( (select ''',''' + ringSize from #tblRingSize For XML PATH('')),1,2,'') +'''' )
,' ',''))
select Replace (
(select STUFF( (select ''',''' + ringSize from #tblRingSize For XML PATH('')),1,2,'') +'''' )
,' ','')

You don't need to use STUFF, FOR XML, or REPLACE for the subquery:
select
ItemSizeNm
from
MstItemSize
where SizeTypeNm ='Ring'
and ItemSizeNm in (select ringSize from #tblRingSize)

Related

Moving Complex Query Results to a Table

I have a complex query that cannot be saved as a view because of the DECLARE statements at the beginning of the query.
I would like to save the results of the query into a table.
I tried to insert the following statement to surround the whole query and also only around the SET #sql and EXEC(#sql).
Both caused errors that I could not resolve.
This is the query that produces the results I need:
DECLARE #sql VARCHAR(MAX)
DECLARE #colList VARCHAR(MAX)
--create dynamic list of columns
SELECT #colList = STUFF((SELECT + ',' + QUOTENAME(colName + CAST(CAST(Billing_Order AS INTEGER) AS VARCHAR))
FROM Credible_Client_Insurance_Raw_Data
CROSS APPLY
(SELECT 1 As Ord, 'Payer_ID' ColName
UNION ALL
SELECT 2 As Ord, 'Billing_Order'
UNION ALL
SELECT 3 As Ord, 'Insurance_ID'
UNION ALL
SELECT 4 As Ord, 'Group_No'
UNION ALL
SELECT 5 As Ord, 'Copay_Fee'
UNION ALL
SELECT 6 As Ord, 'Start_Date') v
GROUP BY colName, Ord, CAST(CAST(Billing_Order AS INTEGER) AS VARCHAR)
ORDER BY CAST(CAST(Billing_Order AS INTEGER) AS VARCHAR), Ord
FOR XML PAT(''), TYPE).value('/', 'VARCHAR(MAX)'), 1, 1, '')
--unpivot columns into rows and then apply pivot
SET #sql = 'SELECT Client_ID, ' + #colList + '
FROM
(SELECT
Client_ID, ColVal,
colName + CAST(CAST(Billing_Order AS INTEGER) AS VARCHAR) ColName
FROM Credible_Client_Insurance_Raw_Data
CROSS APPLY
(
SELECT Payer_ID As ColVal, ''Payer_ID'' ColName UNION ALL
SELECT Billing_Order, ''Billing_Order'' UNION ALL
SELECT Insurance_ID, ''Insurance_ID'' UNION ALL
SELECT Group_No, ''Group_No'' UNION ALL
SELECT CAST(Copay_Fee AS VARCHAR), ''Copay_Fee'' UNION ALL
SELECT CAST(Start_Date AS VARCHAR), ''Start_Date''
) v
) A
PIVOT
(
MAX(ColVal) FOR ColName IN (' + #colList + ')
) P1 '
EXEC(#sql)
I just want to INSERT the query's result set into a permanent table Credible_Client_Insurance_Data.
Is there any way to essentially perform a
INSERT INTO Credible_Client_Insurance_Data (Client_ID, etc.)
SELECT Client_ID, etc.
FROM query_results
Or some type of data insert into the table?
IF I'm understanding correctly, don't you just need to change the value of #sql to:
SET #sql = '
INSERT INTO Credible_Client_Insurance_Data (' + #colList + ')
SELECT Client_ID, ' + #colList + '
FROM
(
SELECT Client_ID, ColVal,
colName + CAST(CAST(Billing_Order AS INTEGER) AS VARCHAR) ColName
FROM Credible_Client_Insurance_Raw_Data
CROSS APPLY
(
SELECT Payer_ID As ColVal, ''Payer_ID'' ColName UNION ALL
SELECT Billing_Order, ''Billing_Order'' UNION ALL
SELECT Insurance_ID, ''Insurance_ID'' UNION ALL
SELECT Group_No, ''Group_No'' UNION ALL
SELECT CAST(Copay_Fee AS VARCHAR), ''Copay_Fee'' UNION ALL
SELECT CAST(Start_Date AS VARCHAR), ''Start_Date''
) v
) A
PIVOT
(
MAX(ColVal) FOR ColName IN (' + #colList + ')
) P1 ;';

SQL Server - PIVOT using variable

I'm trying to do a pivot in SQL Server using a column with a lot of levels. Currently I'm doing a
select '[' + category_1 + '],', count(*)
from myTable
group by '[' + category_1 + '],'
and copying and pasting the output into the text editor.
I was wondering if it's possible to declare a variable and use that as the IN ([],[],[]) information in the pivot command. Has anyone been able to do that?
I think it would look something like this:
#factorLevels = (select '[' + category_1 + '],' from (select category_1, count(*) from myTable) t1)
SELECT *
FROM
(select category_1, item_count from myTable) as t1
PIVOT
(
SUM(item_count)
FOR category_1 IN (#factorLevels)
) as PivotTable;
If I'm understanding you correctly, I think I have a solution. You can use dynamic SQL for this.
You will need to set a variable that contains all the values for the field by which you want to pivot, and then assign the query itself into a variable and execute it to get results:
DECLARE
#values VARCHAR(50),
#querytext VARCHAR(MAX)
;
SET #values = (SELECT '('+(SELECT STUFF(( SELECT ',[' + category_1 +']' FROM
<your table> FOR XML PATH('')), 1, 1, '') )+')')
;
SELECT #querytext =
'SELECT *
FROM (
SELECT
<your fields>
FROM
<your table>
WHERE
<your criteria>
GROUP BY
<your grouping>
) AS Main
PIVOT (
SUM(item_count)
FOR [category_1] IN ' + #values + '
) AS PivotSum'
EXEC sp_executesql #querytext

Convert a row as column and merge two column as its value

I have stuck in a select statement, converting rows into columns. I have tried with PIVOT, i was able to convert the single column. But my requirement is little different. I have explained the requirement below.
I have a table structure as below,
I want to select the data as below,
The values in the table are dynamic, which is not a problem for me to deal with that. But i need a way to get the below result.
Could someone please give me a hint on doing it, may be a way to modify the PIVOT below.
select *
from
(
select TSID,AID,Count,BID
from tbl TS
WHERE TS.TPID = 1
) src
pivot
(
sum(Count)
for AID in (AID1,AID2,AID3)
) piv
Thank you..
You may check this fiddle
EDIT
This will work for not previously known column names
DECLARE #Columns AS VARCHAR(MAX)
DECLARE #SQL AS VARCHAR(MAX)
SELECT #Columns = STUFF(( SELECT DISTINCT ',' + AID
FROM Table1
FOR
XML PATH('')
), 1, 1, '')
SET #SQL = '
;WITH MyCTE AS
(
SELECT TSID,
AID,
STUFF(( SELECT '','' + CONVERT(VARCHAR,[Count] )
FROM Table1 I Where I.TSID = O.TSID
FOR
XML PATH('''')
), 1, 1, '''') AS CountList
FROM Table1 O
GROUP BY TSID,
AID
)
SELECT *
FROM MyCTE
PIVOT
(
MAX(CountList)
FOR AID IN
(
' + #Columns + '
)
) AS PivotTable'
EXEC(#SQL)

How to generate an update query of a dynamic query (automatically)?

I'm storing some queries in a table column so I can execute them later passing some parameters.
But it has been really annoying to format the query into an Update sentence, because of the special characters.
For Example:
SELECT * FROM MOUNTAINS WHERE MON_NAME='PALMA' AND MON_DESC LIKE '%TRANVULCANIA%'
Then I need the string just for the udpate query:
UPDATE QUERIES
SET QUE_SEL='SELECT * FROM MOUNTAINS WHERE MON_NAME='''+'PALMA'+''' AND MON_DESC LIKE '''+'%TRANVULCANIA%'+''' '
WHERE QUE_ID=1
as you can see the first ' must be replaced for '''+' but the next door ' must be replaced by '+'''
This is the query I'm working on:
DECLARE #QUERY VARCHAR(MAX)
SELECT #QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''' '
SELECT
t.r.value('.', 'varchar(255)') AS token
, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(#QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
this is the result:
token id
-------------------------------------------------- --------------------
SELECT * FROM QUERIES WHERE QUE_NOMBRE= 1
' 2
PRUEBA 1 3
' 4
5
Now I want a column that tell me when to open and when to close and then I can set the final replace.
Adapting the solution given by #rivarolle
DECLARE #QUERY VARCHAR(MAX)
DECLARE #FORMATTED varchar(max)
SELECT #QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''''
;WITH TOKENS AS(
SELECT
t.r.value('.', 'varchar(MAX)') AS token
, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(#QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
)
,
Tokens2 as (
SELECT
TOKENS.token as token
,quotes.row%2 as tipoapostrofe
from Tokens
left join (select row_number() over( order by Id asc) as row, a.* FROM (SELECT * from Tokens) a where Token = '''') quotes
on quotes.Id = Tokens.Id
)
SELECT #FORMATTED = STUFF((
SELECT ' ' + REPLACE(token,'''',CASE tipoapostrofe WHEN 1 THEN '''''''+''' WHEN 0 THEN '''+''''''' ELSE '' END) AS [text()]
FROM Tokens2
FOR XML PATH('')
), 1, 1, '')
print #FORMATTED
This Works, just need a function for cleaning XML special characters and another for putting back, and the Dynamic queries are printed ready for an update.
I think its not necessary to replace an apostrophe with '''+' to open and '+''' to close, I made some probes and you can exec a query that you replace opening and closing apostrophes with the same.. for example '''+' for open and '''+' for close.
So the query would be:
DECLARE #QUERY VARCHAR(MAX)
DECLARE #FORMATTED varchar(max)
SELECT #QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''''
SELECT #FORMATTED= STUFF((
SELECT ' ' +
(SELECT
CASE
WHEN t.r.value('.', 'varchar(250)')='''' THEN REPLACE(t.r.value('.', 'varchar(250)'), '''','''''''+''')
ELSE t.r.value('.', 'varchar(250)')
END
) AS [text()]
-- , ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(#QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
FOR XML PATH('')
), 1, 1, '')
SET #FORMATTED=REPLACE(#FORMATTED,' ','')
PRINT #FORMATTED
then I get:
SELECT * FROM QUERIES WHERE QUE_NOMBRE= '''+' PRUEBA 1 '''+'
then I copy into a variable and execute
DECLARE #VAR VARCHAR(500)
SET #VAR='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'''+' '
EXEC(#VAR)
It Works for very simple queries, but with longer and complicated queries it doesn't works..
Assuming your token table is Tokens(Token, Id, Position):
update Tokens
set position = quotes.row%2
from Tokens
left join (select row_number() over( order by Id asc) as row, a.* FROM (SELECT * from Tokens) a where Token = '''') quotes
on quotes.Id = Tokens.Id
The position column will have a value of 1 for starting quote and 0 for closing quote. NULL for the rest.

How to convert string of numbers ( '14, 72' ) to numbers in sql query

declare #lkaklf as varchar(Max)
Select ss.Data from SplitString('14,72', ',') as ss
Select #lkaklf = CONVERT(varchar, COALESCE( + #lkaklf + ',', '') + '''' + Data + '''') From
(
Select Data from SplitString('14,72', ',')
)de
select #lkaklf
print #lkaklf
Select * from LPO Where CONVERT(varchar, LPO.LocalPurchaseOrderId) in (#lkaklf)
#lkalf value is Printing in message but not coming into select query... Why ?
You cannot do what you want. I would recommend that you skip over the splitting part of the query and just do:
where ','+#lkaklf+',' like ','+cast(LPO.LocalPurchaseOrderId as varchar(255))+',%'
That is, just use string comparisons.
If you really want to use SplitString(), then put the results in a temporary table:
insert into #t
select data from splitstring('14,72', ',')
And then use a subquery:
where cast(#lkalklf as varchar(255)) in (select data from #t)