How to get The QueryString Without EXEC and Print Function - sql

I have other table #table3 where the #qur will be stored and using that #qur i want to retrieve the data.
so it is possible to get data without set all query in other variable and execute this query directly.
this string of #qur not fixed it will different for different person.
and yes i use sql server 2010
CREATE TABLE #Table1
([Name] varchar(5), [DateVal] date, [TimeVal] time, [Item] varchar(5))
;
INSERT INTO #Table1
([Name], [DateVal], [TimeVal], [Item])
VALUES
('Lisa', '2015-04-21', '10:20:06', 'Item1'),
('John', '2015-04-21', '10:25:30', 'Item2'),
('Peter', '2015-03-18', '13:35:32', 'Item3'),
('Ralf', '2015-04-03', '09:26:52', 'Item4')
;
CREATE TABLE #Table2
([ID] int, [Name] varchar(5))
;
INSERT INTO #Table2
([ID],[Name])
VALUES
(1,'Lisa' ),
(2,'John' ),
(3,'Peter'),
(4,'Ralf')
;
DECLARE #qur VARCHAR(2000)='([Item] in (''Item1,Item2'')) and [Name]=''Lisa'') '
SELECT DateVal FROM #Table1
WHERE [Name] in (SELECT [Name] FROM #Table2)
AND #qur

Maybe You can use the query bellow in SQLCMD mode:
:setvar qur "and ([Item] in ('Item1','Item2')) and [Name]='Lisa' "
SELECT DateVal FROM #Table1
WHERE [Name] in (SELECT [Name] FROM #Table2)
$(qur)

Related

How to select from string array added in SQL column?

Below is my table,
create table t(
id int,
colParam varchar(max))
insert into t values(1,'["param1", "param2"]')
insert into t values(2,'["param2"]')
insert into t values(3,'["param1"]')
insert into t values(4,'["param2", "param3"]')
insert into t values(5,'["param1", "param2"]')
tried
declare #str varchar(max) = 'param1'; Select * from t where colParam like '%'+ #str+'%'
its not working for
declare #str varchar(max) = 'param1,param2'; Select * from t where colParam like '%'+ #str+'%'
i want to select rows by passing colPar as 'param1,param2' so it will result me all the records containing param1 and param2 in colParam
This quiet tricky.
create table #t(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
declare #str varchar(max) = 'param1,param2';
to Return all matching values.
select distinct id, t1.colParam from #t t1
cross apply string_split(t1.colParam, ',') t2
cross apply string_split(#str, ',') t3
where t2.value like '%'+t3.value+'%'
Output:
If you are using SQL Server 2016 and above, then you can use STRING_SPLIT.
As MSDN says:
A table-valued function that splits a string into rows of substrings,
based on a specified separator character.
So your can look like this:
DECLARE #t TABLE
(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
SELECT
t.id
, s.col
FROM #t AS t
OUTER APPLY
(
SELECT
spl.value AS col
FROM STRING_SPLIT(
(SELECT _t.colParam FROM #t AS _t WHERE _t.id = t.id), ',') AS spl
)s

Concatenate values in sql server and group by another value | ms sql server

I have simple select
select distinct UserName, Company from Users inner join Companies on Users.UserName = Companies.UserFullName
The result of query looks like this:
User1 | Company1
User1 | Company2
User1 | Company3
User1 | Company4
User2 | Company3
User2 | Company6
User2 | Company1
User2 | Company5
I want to concatenate Company values and group it by User. Like this:
User1 | Company1 , Company2 , Company3 , Company4
User2 | Company3 , Company6 , Company1 , Company5
Is it possible thing to do in sql server?
If you are using SQL Server 2017, you can use the new function, STRING_AGG:
SELECT UserName,
STRING_AGG(Company,' , ') WITHIN GROUP (ORDER BY Company) AS Companies
FROM #T1
GROUP BY Username;
Note that you have no ordering in your table, thus the order of 'Company3, Company6, Company1, Company5' cannot be retained for 'User2' unless you have some other column to order by.
The below code snippet would work for you -
CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
INSERT #t1 values ('User1','Company1');
INSERT #t1 values ('User1','Company2');
INSERT #t1 values ('User1','Company3');
INSERT #t1 values ('User1','Company4');
INSERT #t1 values ('User2','Company3');
INSERT #t1 values ('User2','Company6');
INSERT #t1 values ('User2','Company1');
INSERT #t1 values ('User2','Company5');
GO
select
UserName,
stuff((
select ',' + t.[Company]
from #t1 t
where t.UserName = #t1.UserName
order by t.[Company]
for xml path('')
),1,1,'') as CompanyName
from #t1
group by UserName;
Another solution that doesn't require the clause FOR XML PATH
This solution is a loop based
SET NOCOUNT ON
IF OBJECT_ID ('tempdb..#t1') IS NOT NULL DROP TABLE #T1;
IF OBJECT_ID ('tempdb..#t2') IS NOT NULL DROP TABLE #T2;
CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
INSERT #t1 values ('User1','Company1');
INSERT #t1 values ('User1','Company2');
INSERT #t1 values ('User1','Company3');
INSERT #t1 values ('User1','Company4');
INSERT #t1 values ('User2','Company3');
INSERT #t1 values ('User2','Company6');
INSERT #t1 values ('User2','Company1');
INSERT #t1 values ('User2','Company5');
GO
DECLARE #Table TABLE (UserName VARCHAR(100), Combined VARCHAR(4000))
DECLARE #i INT = 1
SELECT DENSE_RANK () OVER (ORDER BY UserName) Seq, *
INTO #T2
FROM #t1
WHILE #i <= (SELECT MAX(Seq) FROM #T2)
BEGIN
DECLARE #ConcatedCompany VARCHAR(4000) = ''
SELECT #ConcatedCompany+= ',' + Company
FROM #T2
WHERE Seq = #i
INSERT INTO #Table (UserName , Combined)
SELECT UserName , STUFF(#ConcatedCompany,1,1,'')
FROM #T2
WHERE Seq = #i
GROUP BY UserName
SET #i +=1
END
SELECT *
FROM #Table
UPDATE!!
Larnu's comment regarding the performance is a good point, usually I'd avoid using WHILE loops and think in terms of set based operations
so, here is the solution without a loop and without "FOR XML PATH"
SET NOCOUNT ON
IF OBJECT_ID ('tempdb..#t1') IS NOT NULL DROP TABLE #T1
IF OBJECT_ID ('tempdb..##T2') IS NOT NULL DROP TABLE ##T2
IF OBJECT_ID ('tempdb..##Table') IS NOT NULL DROP TABLE ##Table
CREATE TABLE #t1 (UserName VARCHAR(100), Company VARCHAR(100));
INSERT #t1 values ('User1','Company1');
INSERT #t1 values ('User1','Company2');
INSERT #t1 values ('User1','Company3');
INSERT #t1 values ('User1','Company4');
INSERT #t1 values ('User2','Company3');
INSERT #t1 values ('User2','Company6');
INSERT #t1 values ('User2','Company1');
INSERT #t1 values ('User2','Company5');
GO
CREATE TABLE ##Table (UserName nvarchar(50), Combined nvarchar(4000))
SELECT DENSE_RANK () OVER (ORDER BY UserName) Seq, *
INTO ##T2
FROM #t1
DECLARE #cmd NVARCHAR(MAX) =''
;WITH T2 (Seq) AS
(
SELECT DISTINCT Seq
FROM ##T2
)
SELECT #cmd += 'DECLARE #ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+' NVARCHAR(4000) = ''''
SELECT #ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+' += '','' + Company FROM ##T2 WHERE Seq = '+CONVERT(VARCHAR(10),Seq)+ CHAR(10)+
' INSERT INTO ##Table (UserName, Combined)
SELECT UserName , STUFF(#ConcatedCompany'+CONVERT(VARCHAR(10),Seq)+',1,1,'''')
FROM ##T2 WHERE Seq = '+CONVERT(VARCHAR(10),Seq) + CHAR(10)+
' GROUP BY UserName '+CHAR(10)+
';'
+CHAR(10)
FROM T2
EXEC sp_executesql #Cmd
SELECT UserName , Combined
FROM ##Table
DROP TABLE ##Table
DROP TABLE ##T2

How to insert keyvalue as a row in table?

I have table variable which contains records in terms of key,value pair of a table. where key is the column of table and value is the value for that column
below is table variable
DECLARE #Table TABLE(
FieldName varchar(100),
FieldValue varchar(max))
insert into #Table values('Title','NewFrom')
insert into #Table values('Points','4')
insert into #Table values('createdby','5')
I have above values in UsersInformation.This is physical table of sql server
has following column.
UserID int autoincrement(identity)
Title nvarchar(100),
Points int,
createdby int
I want that all values of #Table should be as a single row of UserInformation table.
How can be using sql server?
Have not tested but this should work
INSERT INTO UsersInformation (Title, Points, createdby)
SELECT Title, Points, createdby FROM (SELECT FieldName, FieldValue
FROM #Table) AS SourceTable
PIVOT (MAX(FieldValue) FOR FieldName IN ([Points], [Title], [createdby])) AS PivotTable;
Based on your comment you will need to add a key to your source #table
DECLARE #Table TABLE(
id int,
FieldName varchar(100),
FieldValue varchar(max))
insert into #Table values(1,'Title','NewFrom')
insert into #Table values(1,'Points','4')
insert into #Table values(1,'createdby','5')
insert into #Table values(2,'Title','NewFrom2')
insert into #Table values(2,'Points','44')
insert into #Table values(2,'createdby','55')
insert into #Table values(3,'Title','NewFrom3')
insert into #Table values(3,'Points','444')
Then you can run the query:
SELECT [Title], [Points], [createdby]
FROM #Table
PIVOT
(
max(FieldValue) FOR [FieldName] IN ([Title], [Points], [createdby])
) AS P

Iterating through a SQL Server 2008 R2 table variable and concatenate values

I have a table variable #Holding two columns: an id (not unique) and a message:
id message
---- -------
2 give
2 me
2 help
3 Need
3 help
1 help!
The result should be
2 give me help
3 Need help
1 help!
This it very much simplified, but shows that there are id which may exist more than once, and some kind of text which should be concatenated into a string.
I cannot manage it to loop through this table variable (but not through a table too!).
I tried a cursor (which I did not understand correctly) but it failed of course.
The number of records are not that much, not even 100 in that table variable.
Thanks yr. help
Michael
Original question
No CURSOR, WHILE loop, or User-Defined Function needed.
Just need to be creative with FOR XML and PATH.
[Note: This solution only works on SQL 2005 and later. Original question didn't specify the version in use.]
CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)
SELECT
[ID],
STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
This should work if you are using SQL Server.
select T1.id,
stuff((select ' '+T2.[message]
from #A as T2
where T1.id = T2.id
for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '') as [message]
from #A as T1
group by T1.id
Pretty the same, just less letters in the code:
DECLARE #t AS TABLE ( id INT, msg VARCHAR(100) );
INSERT INTO #t
VALUES ( 2, 'give' );
INSERT INTO #t
VALUES ( 2, 'me' );
INSERT INTO #t
VALUES ( 2, 'help' );
INSERT INTO #t
VALUES ( 3, 'Need' );
INSERT INTO #t
VALUES ( 3, 'help' );
INSERT INTO #t
VALUES ( 1, 'help!' );
SELECT DISTINCT
id ,
(
SELECT ST1.msg + ' '
FROM #t ST1
WHERE ST1.id = ST2.id
FOR XML PATH('')
) t
FROM
#t ST2;

Can a Pivot table be used with a unknown number of columns?

If I have a team table with a unknown amount of members, is there a way to make the pivot query dynamic?
create table #t (
team varchar (20), member varchar (20)
)
insert into #t values ('ERP', 'Jack')
insert into #t values ('ERP', 'John')
insert into #t values ('ERP', 'Mary')
insert into #t values ('ERP', 'Tim')
insert into #t values ('CRM', 'Robert')
insert into #t values ('CRM', 'Diana')
select * from #t
select team, [1] as teamMember1, /* 1st select */
[2] as teamMember2, [3] as teamMember3
from
(select team , member, row_number () /* 3rd select */
over (partition by team order by team) as rownum
from #t) a
pivot (max(member) for rownum in ([1], [2], [3])) as pvt
drop table #t
Why yes, yes there is. Here's a script I cooked up years ago for a similar problem that was ultimately solved by giving the user Excel and washing my hands of it. I apologize it's not configured with your example data, but hopefully it's easy to follow.
Hope that helps,
John
--------------START QUERY--------------
-- Example Table
CREATE TABLE #glbTestTable
(
ProviderID INT,
Total INT,
PaymentDate SMALLDATETIME
)
--So the dates insert properly
SET DATEFORMAT dmy
-- Populate Example Table
INSERT INTO #glbTestTable VALUES (232, 12200, '12/01/09')
INSERT INTO #glbTestTable VALUES (456, 10200, '12/01/09')
INSERT INTO #glbTestTable VALUES (563, 11899, '02/03/09')
INSERT INTO #glbTestTable VALUES (221, 5239, '13/04/09')
INSERT INTO #glbTestTable VALUES (987, 7899, '02/03/09')
INSERT INTO #glbTestTable VALUES (1, 1234, '02/08/09')
INSERT INTO #glbTestTable VALUES (2, 4321, '02/07/09')
INSERT INTO #glbTestTable VALUES (3, 5555, '02/06/09')
-- Raw Output
SELECT *
FROM #glbTestTable
-- Build Query for Pivot --
DECLARE #pvtColumns VARCHAR(MAX)
SET #pvtColumns = ''
-- Grab up to the first 1023 "Columns" that we want to use in Pivot Table.
-- Tables can only have 1024 columns at a maximum
SELECT TOP 1023 #pvtColumns = #pvtColumns + '[' + CONVERT(VARCHAR, PaymentDate, 103) + '], '
FROM (SELECT DISTINCT PaymentDate FROM #glbTestTable) t_distFP
-- Create PivotTable Query
DECLARE #myQuery VARCHAR(MAX)
SET #myQuery = '
SELECT ProviderID, ' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + '
FROM (SELECT ProviderID, PaymentDate, Total
FROM #glbTestTable) AS SourceTable
PIVOT
(
SUM(Total)
FOR PaymentDate IN (' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + ')
) AS PivotTable'
-- Run the Pivot Query
EXEC(#myQuery)
-- Cleanup
DROP TABLE #glbTestTable
---------------END QUERY---------------