Trying to concatenate across records [duplicate] - sql

This question already has answers here:
SQL group_concat function in SQL Server [duplicate]
(4 answers)
Closed 8 years ago.
I'm having a bit of a problem that I just can't seem to get my head round. I've got a table that I'm trying to extract some data from. Below is an example of the data.
Id DevId Route
1 1 1
2 1 2
3 1 3
4 1 4
5 2 1
6 2 2
What I want the result to look like would be:
DevId Route
1 1234
2 12
Don't know if I've been looking at it for too long or something, but I just can't work out how to do it.
Any help or suggestions would be greatly appreciated.
Thanks
Alex

Create table ##tmp (id int, name int)
insert into ##tmp values(1,1)
insert into ##tmp values(1,2)
insert into ##tmp values(1,3)
insert into ##tmp values(2,1)
insert into ##tmp values(2,2)
Select id, (Select cast (name as varchar(4))
from ##tmp t2
where t1.id = t2.id
for xml path('')
)
from ##tmp t1
group by id
drop table ##tmp

Related

How to create a query to join multiple rows from a different table into single comma delimated column in SQL Server [duplicate]

This question already has answers here:
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
(12 answers)
Closed 4 years ago.
I am using SQL Server 2014, and I have two tables:
number id
------------------
36-23 1
36-23 2
id value
------------------
1 asia
2 europe
The number column is of type varchar. I want to write a query to return the following results:
number Name
---------------------------
36-23 asia,europe
I am wondering how can I do this with the help of query or functions in SQL Server.
I think using STUFF is the easiest way to go forward here.
CREATE TABLE tableID
([number] varchar(50), [id] int)
;
INSERT INTO tableID
([number], [id])
VALUES
('36-23', 1),
('36-23', 2)
;
CREATE TABLE tableLoc
([id] int, [value] varchar(50))
;
INSERT INTO tableLoc
([id], [value])
VALUES
(1, 'asia'),
(2, 'europe')
;
SELECT tableID.number, tableLoc.value INTO temp1
FROM tableID INNER JOIN tableLoc ON tableID.id = tableLoc.id;
SELECT *, STUFF((
SELECT DISTINCT ', ' + value
FROM temp1
WHERE number = t.number
FOR XML PATH('')), 1, 2, '')
FROM (
SELECT DISTINCT number
FROM temp1
) t

Adding total row and Increasing quality for an sql query based on multiple parameters

I have a table in Microsoft Sql Server 2008 like:
id name timelong
1 Eray 2
1 Jack 1
1 Ali 7
1 john 3
1 Roby 5
1 Mike 4
1 Josh 11
What I want to do is to select data based on user multi-selectable parameters. Think that there are 4 checkboxes: 0-3,4-6,7-9,10-12 and users can select more than one checkbox. Only those data user selected should be seen and a TOTAL row needs to be added at the bottom.
What I tried is on the bottom but it is not working well - TOTAL row is not there. My question is how I can add the Total row there, and is there any more professional way to provide this query. Thanks.
declare #interval03 bit -- 0 to 3
declare #interval06 bit -- 4 to 6
declare #interval09 bit -- 7 to 9
declare #interval12 bit -- 10 to 12
Select *, sum(timelong)
From myTable
Where (#interval03=1 and timelong<4)
or
(#interval06=1 and timelong>3 and timelong<7)
or
(#interval09=1 and timelong>6 and timelong<10)
or
(#interval12=1 and timelong>9 and timelong<13)
group by id, name
Try grouping sets:
Select ID, isnull(Name, 'TOTAL'), sum(timelong)
From myTable
Where (#interval03=1 and timelong <= 3)
or
(#interval06=1 and timelong between 4 and 6)
or
(#interval09=1 and timelong between 7 and 9)
or
(#interval12=1 and timelong >= 10)
group by grouping sets ((ID, name), ())
Assuming from your query that timelong is an int, I've simplified your where a little as well.
More information on grouping sets, rollup, and cube: https://technet.microsoft.com/en-us/library/bb522495(v=sql.105).aspx
TRY This..One more way to add totals...
declare #table Table (id INT,name VARCHAR(10), timelong INT)
insert into #table (id ,name, timelong) VALUES (1, 'Eray', 2)
insert into #table (id ,name, timelong) VALUES (1 ,'Jack' ,1)
insert into #table (id ,name, timelong) VALUES (1 ,'Ali' , 7)
insert into #table (id ,name, timelong) VALUES (1 ,'john' ,3)
insert into #table (id ,name, timelong) VALUES (1 ,'Roby' , 5)
insert into #table (id ,name, timelong) VALUES (1 ,'Mike' ,4)
insert into #table (id ,name, timelong) VALUES (1 ,'Josh' ,11)
declare #interval03 bit=1 -- 0 to 3
declare #interval06 bit -- 4 to 6
declare #interval09 bit -- 7 to 9
declare #interval12 bit -- 10 to 12
DECLARE #result TABLE (ID INT,Name VARCHAR (30),TimeLong INT)
INSERT INTO #result
Select id, name, sum(timelong) timelong
From #table
Where (#interval03=1 and timelong<4)
or (#interval06=1 and timelong>3 and timelong<7)
or (#interval09=1 and timelong>6 and timelong<10)
or (#interval12=1 and timelong>9 and timelong<13)
group by id, name
INSERT INTO #result
SELECT MAX(ID) +100 ID,'Total' Name,SUM(TimeLong) TimeLong
FROM #result
HAVING COUNT(*)<>0
SELECT * FROM #result

SQL Server Row to Cols [duplicate]

This question already has answers here:
Convert Rows to columns using 'Pivot' in SQL Server
(9 answers)
SQL Server: Examples of PIVOTing String data
(7 answers)
Closed 7 years ago.
I seems an simple task but I need some help from the sql experts with this one.
The number of contacts can vary from 1 to 30 persons and I want all the phone numbers in one row per cust_ref.
How can I do this??
This is a solution without dynamic sql, please try out:
declare #contacts table(cust_ref int,phone varchar(100));
insert into #contacts values(10000,'ph10000a'),(10000,'ph10000b'),(10000,'ph10000c')
,(10001,'ph10001a'),(10001,'ph10001b'),(10001,'ph10001c')
,(10002,'ph10002a'),(10002,'ph10002b');
SELECT p.*
FROM
(
SELECT 'phone'+REPLACE(STR(ROW_NUMBER() OVER(PARTITION BY cust_ref ORDER BY phone),2),' ','0') AS inx,*
FROM #contacts
) AS tbl
PIVOT
(
MIN(phone) FOR inx IN(phone01,phone02,phone03,phone04) --type more...
) AS p
by using CROSS APPLY,CTE and UNION ALL we can get the above requirement
declare #tableA table (RefId int,Phone varchar(10))
insert into #tableA (RefId,Phone)values (10000,'030123456'),(100123,060123445)
Declare #tableB table (CustID INT,RefId INT,Phone varchar(10)))
insert into #tableB (CustID,RefId,Phone)values
(1,10000,'030245789'),
(2,10000,'030245889'),
(1,100123,'060245789'),
(2,100123,'060243389'),
(3,100123,'060289389')
; with CTE AS (
select A.RefId,A.Phone As Phone from #tableA A
UNION
select B.RefId,B.Phone As Phone from #tableB B )
select * from (
Select RefId,
val,
COL + CAST(ROW_NUMBER()OVER(PARTITION BY RefId ORDER BY RefId) AS VARCHAR(1))RN
FROM CTE
CROSS APPLY (VALUES ('Phone',Phone))CS(Col,val))T
PIVOT (MAX(VAL) FOR RN IN ([Phone1],[Phone2],[Phone3],[Phone4]))P

Concatenate Rows in SQL with Different values [duplicate]

This question already has answers here:
Concatenate column values for rows with the same values (of different columns)
(3 answers)
Closed 8 years ago.
Hello I have an issue concatinating multiple rows in different tables adding a field separator ; For example. Basically I want to concatenate all values that has the same DocumentsID and they have to have to have different fieldid. If it doesn't have fieldid just leave it blank. Hopefully that makes sense. First time asking here. Thanks again.
DocumentsID Field ID Values
1 190 Jordan
1 191 Kobe
1 192 Rose
2 191 Kobe
Expected Results
DocumentsID Values
1 Jordan; Kobe; Rose
2 Kobe
There's a same question here that you can refer.
I've modified the query used in the accepted answer just to fit in your example.
set nocount on;
declare #YourTable table (DocumentID int, FieldID int, [Values] varchar(50))
insert into #YourTable VALUES (1,190,'Jordan')
insert into #YourTable VALUES (1,191,'Kobe')
insert into #YourTable VALUES (1,192,'Rose')
insert into #YourTable VALUES (2,191,'Kobe')
set nocount off
SELECT DISTINCT
t1.DocumentID
,STUFF(
(SELECT
', ' + t2.[Values]
FROM #YourTable t2
WHERE t1.DocumentID=t2.DocumentID
ORDER BY t2.[Values]
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS [Values]
FROM #YourTable t1
GROUP BY t1.DocumentID,t1.[Values]

Pivot or Cross Tab [duplicate]

This question already has answers here:
Pivot in sql server
(4 answers)
Closed 8 years ago.
I have the two tables which need to be linked and present the data in human friendly way. Could you experts point me in right direction, I am bit stuck here.
Both table 1 and table2 are received through ftp and loaded to SQL table in SQL 2008 R2. These two tables are linked by nid and cid together.
Apologies i couldn't copy paste table here, please consider "-" are column separators
Table 1
ID nid cid pid form_key-name
1 4 1 33 Import_Gen_Title-Title
2 4 2 33 Import_Gen_Firstname-Firstname
3 4 3 33 Import_Gen_Surname-Surname
4 4 4 33 Import_Gen_AddressLine1-AddressLine1
5 4 5 33 Import_Gen_AddressLine2-AddressLine2
6 4 6 33 Import_Gen_City-Town/City
7 4 7 33 Import_Gen_Zip-Post code
Table 2
ID nid sid cid data
1 4 14 1 Mr
2 4 14 2 John
3 4 14 3 Smith
4 4 14 4 A Company
5 4 14 5 Nice Street
6 4 14 6 London
7 4 14 7 SE11 0TS
Now how can get this a Result Table like this one below ?
NiD SID Title Firstname Surname AddressLine1 AddressLine2 Town/City-Post code
4 14 Mr John Smith A Company Nice Street London-SE11 0TS
Check my answer for this same question here: Pivot in sql server
I made a stored procedure that uses the PIVOT statement shown by salvoo - but it's more generic, you don't have to know all the columns in advance.
Take a look.
Here is the example using your data - note that the default output of the pivot has the columns in alphabetical order which you don't want - so I used the option to output the pivot to a temp table then queried directly from the temp table to put the columns in the order you wanted.
drop table Fields
go
drop table Data
go
create table Fields
(
ID Integer,
nid Integer,
cid Integer,
pid Integer,
form_key_name varchar(50)
);
go
create table Data
(
ID Integer,
nid Integer,
sid Integer,
cid Integer,
data varchar(50)
);
go
insert into Fields values (1,4,1,33,'Import_Gen_Title-Title')
go
insert into Fields values (2,4,2,33,'Import_Gen_Firstname-Firstname')
go
insert into Fields values (3,4,3,33,'Import_Gen_Surname-Surname')
go
insert into Fields values (4,4,4,33,'Import_Gen_AddressLine1-AddressLine1')
go
insert into Fields values (5,4,5,33,'Import_Gen_AddressLine2-AddressLine2')
go
insert into Fields values (6,4,6,33,'Import_Gen_City-Town/City')
go
insert into Fields values (7,4,7,33,'Import_Gen_Zip-Post code')
go
insert into Data values (1,4,14,1,'Mr')
go
insert into Data values (2,4,14,2,'John')
go
insert into Data values (3,4,14,3,'Smith')
go
insert into Data values (4,4,14,4,'A Company')
go
insert into Data values (5,4,14,5,'Nice Street')
go
insert into Data values (6,4,14,6,'London')
go
insert into Data values (7,4,14,7,'SE11 0TS')
go
declare #mySQL varchar(MAX);
set #mySQL = '
select
f.nid,
d.sid,
right(f.form_key_name, len(f.form_key_name) - charindex(''-'',f.form_key_name)) form_key_name,
d.data
from
Fields f
JOIN Data d
on ( d.nid = f.nid
and d.cid = f.cid )
';
exec pivot_query #mySQL, 'nid, sid', 'form_key_name','max(data)', '##tmppivot';
select
nid,
sid,
Title,
Firstname,
Surname,
AddressLine1,
AddressLine2,
[Town/City],
[Post code]
from
##tmppivot;
go
With Pivot: Fiddle demo
SELECT sid, nid,
[Import_Gen_Title-Title] as Title,
[Import_Gen_Firstname-Firstname] as Name,
[Import_Gen_Surname-Surname] as SurName,
[Import_Gen_AddressLine1-AddressLine1] as Address1,
[Import_Gen_AddressLine2-AddressLine2] as Address2,
[Import_Gen_City-Town/City] as Town,
[Import_Gen_Zip-Post code] as PostCode
FROM
(
SELECT t2.sid, t2.nid, t2.dat, t1.form_key
FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(
min(x.dat)
for x.form_key in ([Import_Gen_Title-Title],
[Import_Gen_Firstname-Firstname],
[Import_Gen_Surname-Surname],
[Import_Gen_AddressLine1-AddressLine1],
[Import_Gen_AddressLine2-AddressLine2],
[Import_Gen_City-Town/City],
[Import_Gen_Zip-Post code]
)
) pvt
Edit (Added generic version): Fiddle demo
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT ',[' + t.form_key + ']'
FROM tab1 t
group by t.form_key, cid
order by t.cid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT * FROM
(
SELECT t2.sid, t2.nid, t2.dat, t1.form_key
FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(
min(x.dat)
FOR x.form_key IN (' + #cols + ')
) pvt;';
execute(#query);