SQl Server 2005 Pivot - sql

I want to basically join these 3 table in a view for a report:
Class Table:
ID Name
1 N1
2 N2
3 N3
Flags Table:
ID ClassID Flags
1 1 F1
2 1 F2
3 2 F6
4 2 F3
5 3 F2
Sessions Table:
ID ClassID Sessions
1 1 S1
2 1 S4
3 2 S3
4 3 S5
5 3 S4
So my desired view should be something like this:
ID Name Flags Sessions
1 N1 F1,F2 S1,S4
2 N2 F6,F3 S3
3 N3 F2 S5,S4

Select C.Id, C.Name
, Stuff(
(
Select ', ' + F1.Flags
From Flags As F1
Where F1.ClassId = C.Id
Order By F1.Flags
For Xml Path('')
), 1, 2, '') As Flags
, Stuff(
(
Select ', ' + S1.Sessions
From Sessions As S1
Where S1.ClassId = C.Id
Order By S1.Flags
For Xml Path('')
), 1, 2, '') As Sessions
From Class As C

select Class.ID,Name,Flags,Sessions
from Class
inner join flags on class.id = flags.classid
inner join sessions on class.id = sessions.classid

Related

RECURSIVE CTE SQL - Find next available Parent

I have parent child relation SQL table
LOCATIONDETAIL Table
OID NAME PARENTOID
1 HeadSite 0
2 Subsite1 1
3 subsite2 1
4 subsubsite1 2
5 subsubsite2 2
6 subsubsite3 3
RULESETCONFIG
OID LOCATIONDETAILOID VALUE
1 1 30
2 4 15
If i provide Input as LOCATIONDETAIL 6, i should get RULESETCONFIG value as 30
because for
LOCATIONDETAIL 6, parentid is 3 and for LOCATIONDETAIL 3 there is no value in RULESETCONFIG,
LOCATIONDETAIL 3 has parent 1 which has value in RULESETCONFIG
if i provide Input as LOCATIONDETAIL 4, i should get RULESETCONFIG value 15
i have code to populate the tree, but don't know how to find the next available Parent
;WITH GLOBALHIERARCHY AS
(
SELECT A.OID,A.PARENTOID,A.NAME
FROM LOCATIONDETAIL A
WHERE OID = #LOCATIONDETAILOID
UNION ALL
SELECT A.OID,A.PARENTOID,A.NAME
FROM LOCATIONDETAIL A INNER JOIN GLOBALHIERARCHY GH ON A.PARENTOID = GH.OID
)
SELECT * FROM GLOBALHIERARCHY
This will return the next parent with a value. If you want to see all, remove the top 1 from the final select.
dbFiddle
Example
Declare #Fetch int = 4
;with cteHB as (
Select OID
,PARENTOID
,Lvl=1
,NAME
From LOCATIONDETAIL
Where OID=#Fetch
Union All
Select R.OID
,R.PARENTOID
,P.Lvl+1
,R.NAME
From LOCATIONDETAIL R
Join cteHB P on P.PARENTOID = R.OID)
Select Top 1
Lvl = Row_Number() over (Order By A.Lvl Desc )
,A.OID
,A.PARENTOID
,A.NAME
,B.Value
From cteHB A
Left Join RULESETCONFIG B on A.OID=B.OID
Where B.VALUE is not null
and A.OID <> #Fetch
Order By 1 Desc
Returns when #Fetch=4
Lvl OID PARENTOID NAME Value
2 2 1 Subsite1 15
Returns when #Fetch=6
Lvl OID PARENTOID NAME Value
1 1 0 HeadSite 30
This should do the job:
;with LV as (
select OID ID,PARENTOID PID,NAME NAM, VALUE VAL FROM LOCATIONDETAIL
left join RULESETCONFIG ON LOCATIONDETAILOID=OID
), GH as (
select ID gID,PID gPID,NAM gNAM,VAL gVAL from LV where ID=#OID
union all
select ID,PID,NAM,VAL FROM LV INNER JOIN GH ON gVAL is NULL AND gPID=ID
)
select * from GH WHERE gVAL>0
See here for e little demo: http://rextester.com/OXD40496

SQL recursive hierarchy

I am struggling to get one recursive CTE to work as desired but still with no chance..
So, I have the following similar table structures:
tblMapping:
map_id | type_id | name | parent_id
1 1 A1 0
2 1 A2 0
3 1 A3 1
4 1 A4 3
5 2 B1 0
6 2 B2 5
7 2 B3 6
8 1 A5 4
9 2 B4 0
tblRoleGroup:
role_group_id | type_id | map_id | desc_id
1 1 0 null
1 2 0 null
2 1 3 1
2 2 6 0
3 1 8 1
3 2 9 1
In tblRoleGroup, the desc_id field means:
null - allow all (used only in combination with map_id=0)
0 - allow all from parent including parent
1 - allow only current node
Still in tblRoleGroup if map_id=0 then the query should get all elements from same type_id
The query result should look like this:
role_group_id | type_id | map_id | path
1 1 1 A1
1 1 2 A2
1 1 3 A1.A3
1 1 4 A1.A3.A4
1 1 8 A1.A3.A4.A5
1 2 5 B1
1 2 6 B1.B2
1 2 7 B1.B2.B3
1 2 9 B4
2 1 3 A1.A3
2 2 6 B1.B2
2 2 7 B1.B2.B3
3 1 8 A1.A3.A4.A5
3 2 9 B4
The query below solves only a part of the expected result, but I wasn't able to make it work as the expected result..
WITH Hierarchy(map_id, type_id, name, Path) AS
(
SELECT t.map_id, t.type_id, t.name, CAST(t.name AS varchar(MAX)) AS Expr1
FROM dbo.tblMapping AS t
LEFT JOIN dbo.tblMapping AS t1 ON t1.map_id = t.parent_id
WHERE (t1.parent_id=0)
UNION ALL
SELECT t.map_id, t.type_id, t.name, CAST(h.Path + '.' + t.name AS varchar(MAX)) AS Expr1
FROM Hierarchy AS h
JOIN dbo.tblMapping AS t ON t.parent_id = h.map_id
)
SELECT h.map_id, h.type_id, t.role_group_id, h.Path AS Path
FROM Hierarchy AS h
LEFT JOIN dbo.tblRoleGroup t ON t.map_id = h.map_id
Could someone help me on this?
Thank you
At first I create a function that brings all descendants of passed map_id:
CREATE FUNCTION mapping (#map_id int)
RETURNS TABLE
AS
RETURN
(
WITH rec AS (
SELECT map_id,
[type_id],
CAST(name as nvarchar(max)) as name,
parent_id
FROM tblMapping
WHERE map_id = #map_id
UNION ALL
SELECT m.map_id,
m.[type_id],
r.name+'.'+m.name,
m.parent_id
FROM rec r
INNER JOIN tblMapping m
ON m.parent_id = r.map_id
)
SELECT *
FROM rec
);
GO
Then run this:
;WITH rec AS (
SELECT map_id,
[type_id],
CAST(name as nvarchar(max)) as name,
parent_id
FROM tblMapping
WHERE parent_id=0
UNION ALL
SELECT m.map_id,
m.[type_id],
r.name+'.'+m.name,
m.parent_id
FROM rec r
INNER JOIN tblMapping m
ON m.parent_id = r.map_id
)
SELECT t.role_group_id,
r.[type_id],
r.map_id,
r.name as [path]
FROM tblRoleGroup t
CROSS JOIN rec r
WHERE r.[type_id] = CASE WHEN t.desc_id IS NULL AND t.map_id = 0 THEN t.[type_id] ELSE NULL END
OR r.map_id = CASE WHEN t.desc_id = 1 THEN t.map_id ELSE NULL END
OR r.map_id IN (
SELECT map_id
FROM dbo.mapping (CASE WHEN t.desc_id = 0 THEN t.map_id ELSE NULL END)
)
ORDER BY role_group_id, r.[type_id], r.map_id
Will give you:
role_group_id type_id map_id path
1 1 1 A1
1 1 2 A2
1 1 3 A1.A3
1 1 4 A1.A3.A4
1 1 8 A1.A3.A4.A5
1 2 5 B1
1 2 6 B1.B2
1 2 7 B1.B2.B3
1 2 9 B4
2 1 3 A1.A3
2 2 6 B1.B2
2 2 7 B1.B2.B3
3 1 8 A1.A3.A4.A5
3 2 9 B4

Optimized SQL Query to retrieve a Particular set of records from Microsoft SQL Server DB

I want to retrieve the set of data from a column in the table.
My Scenario is:
Iam having a table with name table1_data , In that table there is a Column with name "clm_Name", The data in the column is like this
a
b
c
a
b
c
a
b
a
b
c
a
a
b
c
I want to retrieve the data when a b c are in order if order changes it should not retrieve.(i.e, If we write a query on given data the output should be a b c a b c a b a b c a a b c) only the bolded letters should be shown in output.
If you have a column to sort you can do as follows:
DECLARE #Tbl TABLE (OrderId INT, val NVARCHAR(1))
INSERT INTO #Tbl
VALUES
(1,'a'),
(2,'b'),
(3,'c'),
(4,'a'),
(5,'b'),
(6,'c'),
(7,'a'),
(8,'b'),
(9,'a'),
(10,'b'),
(11,'c'),
(12,'a'),
(13,'a'),
(14,'b'),
(15,'c')
;WITH CTE
AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY (SELECT OrderId)) RowId
FROM #Tbl
), Result
AS
(
SELECT
CurrRow.RowId
FROM
CTE CurrRow LEFT JOIN
(SELECT CTE.val , CTE.RowId - 1 RowId FROM CTE) NextRow ON CurrRow.RowId = NextRow.RowId LEFT JOIN
(SELECT CTE.val , CTE.RowId + 1 RowId FROM CTE) PrivRow ON CurrRow.RowId = PrivRow.RowId
WHERE
PrivRow.val = 'a' AND
CurrRow.val = 'b' AND
NextRow.val = 'c'
)
SELECT
*
FROM
CTE C
WHERE
C.RowId IN (
SELECT Result.RowId FROM Result
UNION ALL
SELECT Result.RowId - 1 FROM Result
UNION ALL
SELECT Result.RowId + 1 FROM Result
)
ORDER BY C.OrderId
Output:
OrderId val RowId
1 a 1
2 b 2
3 c 3
4 a 4
5 b 5
6 c 6
9 a 9
10 b 10
11 c 11
13 a 13
14 b 14
15 c 15

How to display data in below format

My table is:
Id Name Add
1 a A
2 b B
3 c C
4 d D
I want to displaty it as:
Id Name Add Id2 Name2 Add2
1 a A 2 b B
3 c C 4 d D
Use query below
Select LTable.id,LTable.Name,LTable.[Add],
RTable.id,RTable.Name,RTable.[Add]
from
(
Select Row_Number()over ( order by id)as fldkey,id,name , [Add]
from TableName
where id % 2 <> 0
) as LTable INNER JOIN
(
Select Row_Number()over ( order by id)as fldkey,id,name , [Add]
from TableName
where id % 2 = 0
) as RTable
on LTable.fldKey = RTable.fldKey

Parent Child Result from sql server? [duplicate]

This question already has answers here:
How to get result from parent child table
(4 answers)
Closed 9 years ago.
I have a table category as below:
id title ParentID
1 C1 0
2 C2 0
3 C3 0
4 C4 2
5 C5 1
6 C6 3
7 C7 4
I want result as
id title ParentID Level
1 C1 0 0
5 C5 1 1
2 C2 0 0
4 C4 2 1
7 C7 4 2
3 C3 0 0
6 C6 3 1
How can I get this result?
Explanation of the order: I want result with items below their parent item.
This answer assumes that you are using SQL Server 2008 or later.
Use a recursive CTE and build a string of id's that you use in the order by as a hierarchy id.
with C as
(
select id,
title,
parentid,
'/'+cast(id as varchar(max))+'/' as sort,
1 as lvl
from YourTable
where parentid = 0
union all
select T.id,
T.title,
T.parentid,
C.sort + cast(T.id as varchar(10)) + '/',
C.lvl + 1
from YourTable as T
inner join C
on T.parentid = C.id
)
select id,
title,
parentid,
lvl,
sort
from C
order by cast(sort as hierarchyid)
SQL Fiddle
With a recursive CTE, which basically builds the materialized path from root items to items:
; WITH cte
(id, title, parentID, path)
AS
( SELECT
id,
title,
parentID,
CAST(RIGHT(REPLICATE('0',9)
+ CAST(id AS VARCHAR(10))
,10) AS VARCHAR(MAX))
FROM
category
WHERE
parentID = 0
UNION ALL
SELECT
a.id,
a.title,
a.parentID,
CAST(b.path
+ RIGHT(REPLICATE('0',9)
+ CAST(a.id AS VARCHAR(10))
,10) AS VARCHAR(MAX))
FROM
category AS a
JOIN
cte AS b
ON b.id = a.parentID
)
SELECT id, title, parentID
FROM cte
ORDER BY path ;
Test at SQL-Fiddle