I am unable to find the logic for below question in SQL Server.
I have a table like below.
id ParentID
---------------
1 NULL
2 NULL
3 1
4 2
5 3
6 5
I need a query which will return hierarchy of a row, like this:
Hierarchy id ParentID
----------------------------
1 1 NULL
1 2 NULL
2 3 1
2 4 2
3 5 3
4 6 5
I will explain the hierarchy:
For any row if ParentId is null then Hierarchy will be 1
Any row if ParentId is not null and ParentId's ParentId is null then 2
Any row if ParentId is not null, ParentId's ParentId is not null and next ParentId's ParentId is null then 3
And it goes on
How can write the query for this logic.
You can achieve this with a recursive query:
(in the below example your initial table data is stored in #a):
;With DATA AS (
SELECT 1 as hierarchy
,Id
,parentid
from #a
where parentid is null
UNION ALL
SELECT Data.Hierarchy + 1
,a.id
,a.parentid
FROM #a a
INNER JOIN DATA
ON Data.id = a.parentid
)
SELECT *
FROM DATA
ORDER BY hierarchy, Id
Related
I want to copy records from same Table. If parentID is null then I want to copy Parent and Child of that, with another parentName(I'll use replace Key word).
If it is not null then I want to copy that into same parent if same not exists in that parent only.
create table #Table(ID int primary key , Name varchar(10),ParentID int )
insert into #Table
select 1,'Suresh', -1
union
select 2,'Naresh', 1
union
select 3,'John', 1
union
select 4,'Kumar',3
union
Select 5,'Dale John',3
select * from #Table
ID Name ParentID
-------------------
1 Suresh -1
2 Naresh 1
3 John 1
4 Kumar 3
5 Dale John 3
if I select ID = 1, then all ID child should insert into same table if Name not "Suresh" and ParentID not -1.
If I select ID = 3, then ID 3 and Child should insert into same table if Name and ParentID not John & 1
Take those into Temp table and make the join between them.
IF not exists(---)
then insert into table.
I am new to the recursive CTE concept and a problem at hand, I got a tiny feeling that the problem can be solved by using recursive CTE. Let me know what you guys think.
Two tables:
Table one is a self referencing Location table with ID, ParentID, Level and Description.
Table two is an asset table which records individual assets and has a foreign key to Location table ID field.
Table1:
ID Description ParentID Level
1 Site1 NULL 1
2 Site2 NULL 1
3 Building1 1 2
4 Building2 1 2
5 Floor1 3 3
6 Floor2 3 3
7 Floor3 4 3
8 Place1 5 4
9 Place2 7 4
Table2:
ID Description Quantity LocationID
1 Desk 3 8
2 Lamp 1 8
3 PC 10 9
I would like to create a stored procedure with a input parameter of #Level and returns all the Location records at that level and the number of assets within the location (including sub levels).
For example, if #Level = 3, the stored procedure should return:
ID Description AssetCount
5 Floor1 4
6 Floor2 0
7 Floor3 10
If #Level = 2, the stored procedure should return:
ID Description AssetCount
3 Building1 4
4 Building2 10
If the problem is not clear, please let me know.
Well, nothing special here, just a recursive CTE joined with the other table, and the results are what you expected:
declare #level int = 3
;with CTE as (
select id as origid, id, Description, parentid
from table1 where level = #level
union all
select CTE.origid, t1.id, CTE.Description, t1.parentid
from CTE join table1 t1 on
CTE.id = t1.parentid
)
select origid, CTE.description, isnull(sum(t2.Quantity),0) as Quantity
from CTE left outer join table2 t2 on CTE.id = t2.locationid
group by origid, CTE.description
SQL Fiddle
I am in need of stored procedure, I have searched but I didn't get any relevant code.
My requirement is the stored procedure wants to loop the first subquery based on inner subquery.
Select *
from StockInward,
Setup
where StockInward.StockLocation=Setup.Id
AND ProductId in( Select ProductId
from ProductOutward
where Orderid ='38')
The sample table data and output below:
Product Outward table
Id Orderid Productid Qty
1 38 7 2
2 38 6 1
Stockinward table
Id ProductId BranchId Qty
1 7 1 12
2 6 1 2
3 7 2 2
Setup table
BranchId Branchname
1 Xyz
2 ABC
The output need to be:
ProductId Branches
7 Xyz(12) Abc(2 )
6 Xyz(2) -
I want a SQL query to display the following data
Input Data:
ID GroupID Data
1 1 Hello
2 1 Null
3 1 Null
4 1 World
5 2 Niladri
6 2 XXX
7 2 Null
8 2 PPP
9 2 Null
10 2 Null
11 2 Null
12 2 LLL
as
Output Data:
GroupID MergedData
1 Hello2World
2 NiladriXXX1PPP3LLL
I need to group the data on GroupID and display the result as Hello2World
-->Hello is related to GroupID 1
-->2 is count of NULLS
-->World is related to GroupID 1
Similarly for GroupID 2.
Kindly suggest?
Thanks
As you did not mention your DBMS, this is a solution for PostgreSQL:
SELECT groupid,
string_agg(temp_data,'')
FROM (
SELECT id,
groupid,
data,
CASE
WHEN data IS NULL
THEN cast(max(rn) over (partition by groupid, data) as varchar)
ELSE data
END AS temp_data,
row_number() over (partition by groupid, data) as group_rn
FROM (
SELECT id,
groupid,
data,
CASE
WHEN data IS NULL
THEN row_number() over (partition by groupid,data)
ELSE NULL
END AS rn
FROM foo
) t1
ORDER BY id
) t2
WHERE group_rn in (0,1)
GROUP BY groupid
If your DBMS supports ANSI windowing functions and has something similar like the string_agg() function then this should be portable to your DBMS as well.
I have a table like this:
id name parent_id
1 ab1 3
2 ab2 5
3 ab3 2
4 ab4 null
5 ab5 null
6 ab6 null
I need to do a query with input id = 1 (for an example) and results will be like this:
id name parent_id
5 ab5 null
2 ab2 5
3 ab3 2
1 ab1 3
(List all parents at all level start at item id = 1)
Something like this perhaps?
WITH parents(id,name,parent,level)
AS
(
SELECT
ID,
NAME,
PARENT,
0 as level
FROM
TABLE
WHERE ID = 1
UNION ALL
SELECT
ID,
NAME,
PARENT,
Level + 1
FROM
TABLE
WHERE
id = (SELECT TOP 1 parent FROM parents order by level desc)
)
SELECT * FROM parents
Use WITH RECURSIVE. Documentation and adaptable example: Recursive Queries Using Common Table Expressions.