TSQL get column names from dynamic query with formatting/conditions - sql

I need to identify list of columns and its original value from dynamic SQL.
Example: I have this SQL statement:
#tsql = N'SELECT A.ID AS PROCESSID, COALESCE(STEP_ID,'''') AS programmid, NAME FROM DBO.TBL_LOG A'
As per this solution It will just return column name. I need both column name and its original value.
Expected result :
Can anyone please help with this? Thank you in advance.

Below code works for me temporary , If there will be too complex statement in select clause than it will not work.
;WITH CTE AS
(
SELECT NAME , SUBSTRING(LTRIM(#TSQL),7,CHARINDEX('FROM',LTRIM(#TSQL),0)-7) as QRY FROM sys.dm_exec_describe_first_result_set (#TSQL, null, 0)
)
,COLPOS as
(
select NAME,QRY, CHARINDEX(NAME ,QRY,LEN(QRY) - CHARINDEX(REVERSE(NAME),REVERSE(QRY),0)- LEN(NAME)) AS POS
FROM CTE
)
,POS AS (
SELECT NAME,QRY,POS,LAG(POS) OVER (order by (select 1)) LGPOS,LEAD(POS) OVER (order by (select 1)) LEADPOS
,LAG(NAME) OVER (order by (select 1)) LGNAME
FROM COLPOS
)
SELECT NAME , LTRIM(RTRIM(SUBSTRING (QRY,COALESCE(LGPOS+LEN(LGNAME),0),POS+LEN(NAME)-COALESCE(LGPOS+LEN(LGNAME),0)))) AS EXPRESSION
FROM POS

Related

Converting rows to columns without any calculation

I have a table with only a single column. How can I convert these rows to columns?
ColourCode
#FFCC00
#339966
#800080
#FF9900
The maximum possible number of rows will be 10.
I am expecting this:-
C1
C2
C3
C4
#FFCC00
#339966
#800080
#FF9900
I don't know how to dynamic generated column name, if you can combie sql script, you can use combined string to script to execute .
with code as (
select '#FFCC00' as ColourCode
union
select '#339966' as ColourCode
union
select '#800080' as ColourCode
union
select '#FF9900' as ColourCode )
select *
from
(select ColourCode ,
'C' + cast( ROW_NUMBER() OVER (Order by (select 1)) as nvarchar(max)) as rn -- generate sequence number
from code ) as sourcetable
PIVOT
(
max(ColourCode)
FOR rn IN ([C1],[C2],[C3],[C4]) -- predifned column Name, if you want to dynamic generated, you should use variable
) AS PivotTable;

Convert from single column to multiple Column in sql Server

i have tried with below code. but i didnt get ouput as per multiple column.
select Name=stuff((select ','+
name from Input t1 WHERE t1.Name=t2.name for xml path('')),1,9,''),NAME
=stuff((select ','+
name from Input t1 WHERE t1.Name=t2.name for xml path('')),1,1,'')FROM
Input T2
GROUP BY NAME
I have separated the character and numeric parts of the given string in CTE and used a simple group by and sum clause on that.
;With CTE
As
(
Select
Left(Names, 1) As String,
SUBSTRING(Names, 2, Len(Names) - 1) As Number
From SeparateColumns
)
Select
String,
Sum(Cast(Number As Int)) As SumOfDigits
From CTE
Group By String
Order By String;
Assuming you will have single character in your column, the following code works
CREATE TABLE #TEMP_SPLIT
(VALUE VARCHAR(25))
INSERT INTO #TEMP_SPLIT
SELECT 'A10'
UNION
SELECT 'B20'
UNION
SELECT 'A30'
UNION
SELECT 'B40'
UNION
SELECT 'A10'
UNION
SELECT 'C1'
SELECT c, sum(tot)
FROM
(
SELECT SUBSTRING(VALUE,1,1) c ,CONVERT(FLOAT,SUBSTRING(VALUE,2,LEN (VALUE)-1)) Tot
FROM #TEMP_SPLIT
)T
GROUP BY C
DROP TABLE #TEMP_SPLIT
If the names column is always in the specified format, then use LEFT function to extract the character part and RIGHT function to extract the digits part and use these two in the sub-query and use GROUP BY clause and SUM function.
Query
select t.col_a as [string character],
sum(cast(t.col_b as int)) as [sum of digits] from(
select left(names, 1) as col_a,
right(names, len(names) - 1) as col_b
from [your_table_name]
) t
group by t.col_a;
Find a example here
You could use PATINDEX() with SUBSTRING() function if names always in this specified format
select A.CHAR [Strings], SUM(CAST(A.VALUE AS INT)) [Sum] from
(
SELECT SUBSTRING(Name, 1, PATINDEX('%[^A-Z]%', Name)-1) [CHAR], SUBSTRING(Name, PATINDEX('%[0-9]%', Name), len(Name)) [VALUE] FROM <table>
) a GROUP BY A.CHAR
Here's simple solution using subquery and group by clause:
select [StringChar], SUM([Number]) from (
select SUBSTRING(Names, 1, 1) as [StringChar],
convert(int, SUBSTRING(Names, 2, LEN(Names))) as [Number]
from [Input]
) as a group by [StringChar]

SQL - multi select query returning no results

I have a query where I'm trying to select a Row Number from a table that meets a certain criteria from a separate table.
The current query returns 0 results when I'm expecting 1 number
SELECT
RowNum
FROM
(SELECT
ID, Name, RowNum = ROW_NUMBER() OVER (ORDER BY ID)
FROM
tblEncroachmentTypes) AS temp
WHERE
temp.Name LIKE (SELECT EN_TYPE
FROM LakeEncroachments
WHERE EN_ID = '0526')
I have created a temp table to try and simplify it, but it still returns no results
select RowNum
from #temp1
where #temp1.Name like (select EN_TYPE from LakeEncroachments where EN_ID = '0526')
I'm trying to give as much information as possible, but not sure what else I need.
If you need to use like, you might need to add the wildcards:
SELECT RowNum
from (Select ID, Name, RowNum = ROW_NUMBER() over (order by ID) from tblEncroachmentTypes) as temp
where temp.Name Like '%'+(Select EN_TYPE from LakeEncroachments WHERE EN_ID = '0526')+'%'
reformat looks like this:
select RowNum
from (
select ID
, name
, RowNum = row_number() over (
order by ID
)
from tblEncroachmentTypes
) as temp
where temp.name like '%' + (
select EN_TYPE
from LakeEncroachments
where EN_ID = '0526'
) + '%'
Also, if your sub query for like returns more than one value, you'll need a different approach.
if your subquery give multiple rows, use this query
WITH temp as
(SELECT ID, Name, ROW_NUMBER() OVER (ORDER BY ID) as RowNum
FROM tblEncroachmentTypes) AS temp
SELECT temp.RowNum
FROM LakeEncroachments
INNER JOIN temp ON temp.Name LIKE REPLACE(REPLACE(LakeEncroachments.EN_TYPE, '-', '% '), ' ', '% ') + '%'
WHERE EN_ID = '0526'

How can i use the replace statement in query

I am trying to query a table that has values separated by commas as follows:
SELECT ID, NAME,FULLNAME,STATUS,STORE
FROM EMPLOYEE
WHERE STORE IN (SELECT '''' + REPLACE('001,002',',',''',''') +'''')
ORDER BY STORE
when I run the query above, it produces no results,
but when I run it like this:
SELECT ID, NAME,FULLNAME,STATUS,STORE
FROM EMPLOYEE
WHERE STORE IN ('001','002')
ORDER BY STORE
I get like 500 records.
And when I try this:
SELECT ('''' + REPLACE('001,002',',',''',''') +'''')
I get the result '001','002'
so my question is, why the first script does not work, and produces no results?
Is there something I must add to the script for it to work?
please advise.
What if I had this scenario
SELECT ID, NAME,FULLNAME,STATUS,STORE
FROM dbo.EMPLOYEE
WHERE STORE IN (
SELECT t2.ID
FROM (
SELECT Value = REPLACE('001,002', ',', '.')
) t
CROSS APPLY (
VALUES
(PARSENAME(t.Value, 1)),
(PARSENAME(t.Value, 2))
) t2 (ID)
)
AND STATUS IN (
SELECT t2.ID1
FROM (
SELECT Value1 = REPLACE('A,T,L', ',', '.')
) t1
CROSS APPLY (
VALUES
(PARSENAME(t1.Value1, 1)),
(PARSENAME(t1.Value1, 2))
) t2 (ID1)
)
ORDER BY STORE
I tried that, and it didn't work, so I am just wondering if it works for more than 1 condition.

How to show query result in group? SQL Query

Right now my sql query display the result as follows.
though it is the correct result.
I prefer to have the have the result to show as follows.
How can I do this with SQL ? I am on SQL server 2008
I'm with the commenters, better to do this elsewhere, but it's simple enough in SQL using a CASE statement and the ROW_NUMBER() function:
;WITH cte AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT 1)) RN
FROM YourTable)
SELECT CASE WHEN RN = 1 THEN CAST(ID AS VARCHAR(5)) ELSE '' END, Name
FROM cte
ORDER BY ID,RN
Demo: SQL Fiddle
This is not a job for SQL.
Any way, you can easily display it with comma separated values:
ID Names
1000 Honda, Toyota,...
1000 Honda, Toyota,...
SELECT ID, Names=
STUFF((SELECT ', ' + Name
FROM your_table b
WHERE b.ID= a.ID
FOR XML PATH('')), 1, 2, '')
FROM your_table a
GROUP BY ID