Help with TSQL join query - sql

Based on below 2 tables
declare #t1 table
(
Id int,
Title varchar(100),
RelatedId int
)
insert into #t1 values(1,'A',2)
insert into #t1 values(1,'A',3)
declare #t2 table
(
Id int,
Title varchar(100)
)
insert into #t2 values
(2,'B'),
(3,'C')
I am trying to get the below output
Id Title RelatedItems
---------------------------------
1 A 2 (B), 3 (C)
I tried the following:
select t1.Id,t1.Title, cast(t2.Id as varchar) + ' (' + t2.Title + ')' from #t1 as t1
left outer join #t2 as t2
on t1.RelatedId=t2.Id
But that gives 2 different rows. I want just one row with the data combined in the third column (as shown above). Pls. suggest.

Use:
SELECT DISTINCT
b.id,
b.title,
STUFF((SELECT ','+ CAST(t2.id AS VARCHAR(100)) + ' ('+ t2.title +')'
FROM t2
JOIN t1 a ON a.relatedid = t2.id
WHERE a.id = b.id
FOR XML PATH('')), 1, 1, '')
FROM t1 b

Related

create one row from two columns sql

How to create one row from two columns?
Example:
id description
------------------
1 one
2 two
3 three
In result:
1: one, 2: two, 3: three
I use follow statment:
select Id,
stuff((SELECT distinct ', ' + cast(Description as varchar(10))
FROM dbo.tbl t2
where t2.Id = t1.Id
FOR XML PATH('')),1,1,'')
from dbo.tbl t1
group by Id
But in result I have two columns. I need one such as string
You can try this query.
CREATE TABLE T (
id int,
description varchar(50)
);
INSERT INTO T VALUES (1,'one');
INSERT INTO T VALUES (2,'two');
INSERT INTO T VALUES (3,'three');
Query 1:
select
stuff((SELECT ', ' + CAST(t2.ID AS VARCHAR(5)) + ':'+ t2.description
FROM t t2
FOR XML PATH('')),1,1,'')
Results:
| |
|------------------------|
| 1:one, 2:two, 3:three |
i think you are asking for this
select stuff((SELECT ', ' + CAST(tbl.id AS varchar) + ':' + tbl.description
FROM tablename tbl FOR XML PATH('')), 1, 1, '') as Columnname
You were close..
declare #T TABLE (
id int,
description varchar(50)
);
INSERT INTO #T VALUES (1,'one');
INSERT INTO #T VALUES (2,'two');
INSERT INTO #T VALUES (3,'three');
select Id,
stuff((SELECT distinct ', ' + +cast(id as nvarchar) +':'+description
FROM #T t2
where t2.Id = t1.Id
FOR XML PATH('')),1,1,'')
from #T t1
group by Id
OR If you want all the ids in a sing row use the below query
select stuff((select ',' +cast(id as nvarchar) +':'+description
from #T for xml path('')),1,1,'')
select statement is like a for loop or an iterator and you you need a space to save you data and it's not possible with select only because in the moment select statement only access to a row not previous row and not next row so
please use a scaler-value function
create function test()
return
nvarchar(max)
as
begin
declare #s nvarchar(max)
select #s = concate(#s, id, description)
from yourTable
return #s
end

How to remove non repeating character from string in SQL using fuction or SP?

I have 2 columns
1st have string like: '7,8,9,0,3'
2nd have string like: '7,8,5,6,1'
I want output like this: 9,0,3 and 5,6,1 or both combined as 9,0,3,5,6,1
Convert the below code to SP:
DECLARE #Col1 VARCHAR(100)= '7,8,9,0,3', #Col2 VARCHAR(100)= '7,8,5,6,1'
DECLARE #Table1 Table (Col1 VARCHAR(100))
DECLARE #Table2 Table (Col2 VARCHAR(100))
INSERT INTO #Table1 VALUES ( #Col1)
INSERT INTO #Table2 VALUES (#Col2)
;with tmp( Data,Col1) as (
select CONVERT(VARCHAR(100),LEFT(Col1, CHARINDEX(',',Col1+',')-1)),
STUFF(Col1, 1, CHARINDEX(',',Col1+','), '')
FROM #Table1
union all
select CONVERT(VARCHAR(100),LEFT(Col1, CHARINDEX(',',Col1+',')-1)),
STUFF(Col1, 1, CHARINDEX(',',Col1+','), '')
FROM tmp
WHERE Col1>''
)
select ID = IDENTITY(INT,1,1),CONVERT(VARCHAR(100),Data) AS Col1
INTO #T1
from tmp
;with tmp( Data,Col2) as (
select CONVERT(VARCHAR(100),LEFT(Col2, CHARINDEX(',',Col2+',')-1)),
STUFF(Col2, 1, CHARINDEX(',',Col2+','), '')
FROM #Table2
union all
select CONVERT(VARCHAR(100),LEFT(Col2, CHARINDEX(',',Col2+',')-1)),
STUFF(Col2, 1, CHARINDEX(',',Col2+','), '')
FROM tmp
WHERE Col2>''
)
select ID = IDENTITY(INT,1,1),CONVERT(VARCHAR(100),Data) AS Col2
INTO #T2
from tmp
SELECT ID = IDENTITY(INT,1,1),Col1
INTO #T3
FROM
(
SELECT Col1
FROM #T1
EXCEPT
SELECT *
FROM
(
SELECT Col1
FROM #T1
INTERSECT
SELECT Col2
FROM #T2
)T3
UNION ALL
SELECT Col2
FROM #T2
EXCEPT
SELECT *
FROM
(
SELECT Col1
FROM #T1
INTERSECT
SELECT Col2
FROM #T2
)T4
)T5
SELECT DISTINCT STUFF((SELECT ',' + Col1
FROM #T3 T1
--WHERE T1.ID=T2.Id
FOR XML PATH ('')),1,1,'')
FROM #T3 T2
DROP TABLE #T1,#T2,#T3
Demo
What you need to do is full outer join on the same table between the 2 columns.
SELECT distinct A.name1,B.name2
FROM <TABLE> A full outer join <TABLE> B on A.name1 = B.name2
where A.name1 is null or B.name2 is null

sql Id concatenation in sequence in a separate column like running total

I need running Id concatenation just like running balance or total..
Concatenate the previous Ids to current Id row wise just like shown in picture
query is
with relation (Id, [orderSequence])
as
(
select Id,cast(Id as varchar(20))
from [ACChartofAccount]
union all
select p.Id, cast(Cast(r.Id as varchar) + ',' + cast(p.Id as varchar) as varchar(20))
from [ACChartofAccount] p
inner join relation r on p.ParentId = r.Id
)
select Id,orderSequence
from relation
order by orderSequence
You can use below query to get above result.
DECLARE #Table TABLE(ID VARCHAR(10));
INSERT INTO #table(ID) VALUES ('320'),(332),(333),(334),(335);
SELECT mt.ID,
STUFF((
SELECT ', ' + ID
FROM #table t
WHERE t.ID <= mt.ID
FOR XML PATH('')), 1, 2, '') AS oldersequence
FROM #table mt
ORDER BY ID

How to group a table, at the same time saving all column values in each group to a single column as comma-separated values

Please see the following SQL code.
Declare #LookUp table (id int,val varchar(12))
insert into #LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')
Declare #summary table (id int,val varchar(2000))
------------------------------
Declare #value varchar(30)
Declare #start int = 1, #end int = (Select count(Distinct id) from #LookUp)
While #start <= #end
Begin
Set #value = ''
Select #value = #value + '|' + val From #LookUp Where id = #start
Insert into #summary
Select #start,Right(#value,Len(#value)-1)
Set #start = #start + 1
End
Select * From #summary
With the following query, I am grouping based on Id, and making the values with in a group, as comma-separated values.
Input:
Output:
I have done this using a loop, which is not performing very well when it comes to large amount of data.
Can we do this avoiding a loop?
Note: Assume that #lookup.id is continuous.
INSERT #summary(id, val)
SELECT
t.id,
STUFF((
select '|' + [val]
from #LookUp t1
where t1.id = t.id
for xml path(''), type
).value('.', 'varchar(max)'), 1, 1, '') [values]
FROM #LookUp t
GROUP BY t.id
Try this..
Declare #LookUp table (id int,val varchar(12))
insert into #LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')
select
id,
val =
stuff((
select
'| ' + t2.val
from #LookUp t2
where
t2.id = t1.id
group by t2.val
for xml path(''), type).value('.', 'varchar(max)'
), 1, 2, '')
from #LookUp t1
GROUP BY t1.id
Declare #LookUp table (id int,val varchar(12))
insert into #LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F');
WITH A AS
(
SELECT DISTINCT id
FROM #LookUp
)
SELECT
A.id,
STUFF
(
(
SELECT ',' + val
FROM #LookUp B
WHERE B.id = A.id
FOR XML PATH('')
),
1, 1, ''
) AS val
FROM A
Declare #LookUp table (id int,val varchar(12))
insert into #LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')
SELECT DISTINCT a.id, stuff((select '|' + val
from #LookUp c
where c.id = a.id
for xml path('')),1,1,'') as vall
FROM #LookUp a
I'll add a solution based on a recursive common table expression. With small modifications it should work in DB2 too (you have to change the row_number() function to rownumber() and how the concatenation works in the second list (use || instead of the concat function).
DECLARE #LookUp TABLE (id int, val varchar(12))
INSERT INTO #LookUp VALUES (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')
;WITH
list1(rn, id, val) AS
(
SELECT row_number() OVER (PARTITION BY id ORDER BY id), id, val
FROM #LookUp
),
list2 (id, val, idx) AS
(
SELECT id, val, 1
FROM list1
WHERE rn = 1
UNION ALL
SELECT
list2.id,
CAST(CONCAT(list2.val, ' | ', list1.val) AS varchar(12)),
list2.idx + 1
FROM list2
JOIN list1 ON list2.id = list1.id
WHERE list2.idx + 1 = list1.rn
)
SELECT l2.id, l2.val
FROM list2 l2
JOIN (SELECT id, MAX(rn) maxid FROM list1 GROUP BY id) a
ON l2.id = a.id AND l2.idx = a.maxid
ORDER BY l2.id
This outputs:
id val
1 A | D | X
2 B | F

How to make 2 rows into single row in sql

I have a query
example
Title Description
A XYZ
A ABC
now i want a sql query so that i can get a single row
Output :
Title Description
A XYZ | ABC
Declare #tbl table(Title nvarchar(1),[Description] nvarchar(100))
Insert into #tbl values('A','XYZ');
Insert into #tbl values('A','ABC');
Insert into #tbl values('A','PQR');
DECLARE #CSVList varchar(100)
SELECT #CSVList = COALESCE(#CSVList + ' | ', '') +
[Description]
FROM #tbl
WHERE Title='A'
SELECT #CSVList
declare #table table (i int, a varchar(10))
insert into #table
select 1, 'ABC' union all
select 1, 'XYZ' union all
select 2, '123'
select t.i,
max(stuff(d.i, 1, 1, '')) [iList]
from #table t
cross
apply ( select '|' + a
from #table [tt]
where t.i = tt.i
for xml path('')
) as d(i)
group
by t.i;
In mysql there is a group_concat function, that can help you.
Use it like this:
SELECT Title,GROUP_CONCAT(Description) FROM table_name GROUP BY Title
The output will be
Title Description
A XYZ,ABC
Then you can replace "," with "|" if you want(it can be done with replace function)
For 2 rows you can self join in SQL Server. This avoids the assorted "concatenate rows into a column" tricks. You can use a LEFT JOIN and NULL handling too for 1 or 2 rows
SELECT
T1.Title,
T1.Description + '|' + T2.Description
FROM
MyTable T1
JOIN
MyTable T2 ON T1.Title = T2.Title
SELECT
T1.Title,
T1.Description + ISNULL('|' + T2.Description, '') --COALESCE for the pedants)
FROM
MyTable T1
LEFT JOIN
MyTable T2 ON T1.Title = T2.Title
If you are using SQL Server, try this: How to return 1 single row data from 2 different tables with dynamic contents in sql