How to get hierarchy from multiple values on SQL Server? - sql

I have table RD with only one column:
-----
rd_id
-----
3
2
6
7
8
I have table DL with two columns, there is hierarchy on stored on this table:
----------------------
dl_id dl_parent
----------------------
1 2
2 Null
3 Null
4 6
6 7
7 8
8 Null
Now the problem is how to get the hierarchy out from DL table using the member of RD table.
The result will be:
--------------
rd_id dl_id
--------------
3 3
2 2
6 6
6 7
6 8
7 7
8 8
8 8
I've been toiling with this problem from Friday and still can't get crack of it.
I know that I can use Common Table Expression to traverse the recursive from one value (like example create one function with input 6 and produce 6,7,8).
but I don't know how to use multiple value (rd_id).
Have some ideas?

This produces the correct results. Data setup:
declare #RD table (rd_id int not null)
insert into #RD(rd_id) values
(3),
(2),
(6),
(7),
(8)
declare #DL table (dl_id int not null,dl_parent int null)
insert into #DL(dl_id,dl_parent) values
(1,2),
(2,Null),
(3,Null),
(4,6),
(6,7),
(7,8),
(8,Null)
And the query:
;with AllValues as (
select rd_id,rd_id as dl_id from #RD
union all
select rd_id,dl_parent
from AllValues av
inner join
#DL dl
on
av.dl_id = dl.dl_id
where
dl.dl_parent is not null
)
select * from AllValues
Result:
rd_id dl_id
----------- -----------
3 3
2 2
6 6
7 7
8 8
7 8
6 7
6 8
Explanation:
In the anchor of the CTE, we simply select rd_id from the #RD table twice - since your sample implies that every input row should produce an output row with the same value in both columns.
We then join to the #DL table for any matching parent rows we can find, based on the second column. If we find a parent, then we produce a new row, substituting the parent value into the second column. This continues until no new rows are produced.

You have to use on-the-fly views to create a recursive query like this:
with n as (
select dl_id, dl_id as ancestor
from dbo.dl
union all
select np1.dl_id, n.ancestor
from dl as np1 , n
where n.dl_id = np1.dl_parent)
select * from n
where dl_id in (select rd_id from rd)
order by dl_id, ancestor

Related

In sequelize, how do I select records that match all values that i am searching for?

As an example, I have the following table:
T | S
------
1 | 5
1 | 6
1 | 7
2 | 6
2 | 7
3 | 6
Query: array [1,2]
I want to select all values in S that have the value 1 AND 2 in the T Column.
So in the above example I should get as a result (6,7) because only 6 and 7 have for column T the values 1 and 2.
But i do not want to have 5 in my results as 5 does not have 2 in the T column.
How would I do this in sequelize?
how do i make (1,2) to be used as an array?
Either you insert the array joined as comma-separated literal into the query text (variant 1) or you join the array into one string literal and transfer it iinto the query as a parameter (variant 2).
Variant 1
SELECT s
FROM sourcetable
WHERE t IN (1,2) -- separate filter values
GROUP BY s
HAVING COUNT(DISTINCT t) = 2 -- unique values count
Variant 2
SELECT s
FROM sourcetable
WHERE FIND_IN_SET(t, '1,2') -- separate filter values
GROUP BY s
HAVING COUNT(DISTINCT t) = 2 -- unique values count
If (s,t) is unique then DISTINCT keyword may be removed.

Postgresql query to get sum of tree

Hi guys I would like to ask about postgresql and what could be the best query to get sum of column when you have table of elements that has some descendants of more levels ie.
id id_parentvalue
1 null 3
2 null 4
3 1 2
4 2 3
5 3 4
6 3 2
7 4 5
8 4 7
so the result would be rows with sum of all of their tree as follows
value of ids 5 and 6 together is 6 plus value of their parent would be 8 plus his parent would be 11, and same for items with id 7 and 8 so the grandĖ‡parent with id=2 would have value 19
id id_parentvalue
1 null 11
2 null 19
thanks in advance
Use recursive CTEs:
with recursive cte as (
select t.id, t.value, ultimate_parent as id
from t
where id_parent is null
union all
select t.id, t.value, cte.ultimate_parent
from cte join
t
on t.id_parent = cte.id
)
select ultimate_parent, sum(value)
from cte
group by ultimate_parent;
The recursive part starts with the ultimate parents -- the records whose parent is NULL. It then brings in lower levels, step-by-step, keeping the id of the ultimate parent.
The final aggregation just sums the values together.

How to select parent child till end using root parent id in sql?

Below the table :
I need to get without recursion, but use any other join and union.
Id ParentId
1 0
2 1
3 2
4 2
5 4
6 5
7 6
8 7
9 8
N N
Without recursion use any other join queries
DECLARE #Nvalue INT = 10
SELECT NUMBER AS ID,NUMBER-1 AS ParentID FROM (
SELECT DISTINCT NUMBER FROM master..spt_values WHERE number BETWEEN 1 AND #Nvalue
)T

SQL copy from one table to another with changing ID value

I have two tables:
A
ID VALUE
----------
1 7
2 5
3 44
4 982
5 1
6 0
7 671
B
ID VALUE
---------------
1 6
2 6
3 77
4 22
How do I copy data from #B to #A to get a different ID (one bigger than the MAX in #A)? For example I need to get
ID VALUE
1 7
2 5
3 44
4 982
5 1
6 0
7 671
8 6
9 6
10 77
11 22
Either make it an IDENTITY column which auto-increments, or this:
INSERT INTO A
SELECT b.ID + (SELECT MAX(ID) FROM A) AS ID, b.Value
FROM B
DEMO
The select is slightly different if the ID in table B has gaps. Then those gaps are transferred.
If the ID column in TableA is not already set to auto-increment, do the following command:
ALTER TABLE TableA MODIFY COLUMN ID INT auto_increment
Now you can just insert all the records from TableB into TableA:
INSERT INTO TableA (VALUE)
SELECT VALUE
FROM TableB
It is not a great idea to rely on the business logic in your query to maintain the order of the ID column. Instead, let SQL take care of it for you; it was designed for this purpose.

SQL - Add value with previous row only

I have a table named myvals with the following fields:
ID number
-- -------
1 7
2 3
3 4
4 0
5 9
Starting on 2nd row, I would like to add the number with the previous row number. So, my end result would look like this
ID number
-- ------
1 7
2 10
3 7
4 4
5 9
You could use the LAG analytic function
SELECT Id, number + LAG(number,1,0) OVER (ORDER BY Id) FROM table
First thing's first. You can't add to null to ID 1 must have a value.
create table #temp
(
month_type datetime,
value int
)
insert into #temp
Select '2015/01/01',1
union
Select '2015/02/01',2
union
Select '2015/03/01',3
union
Select '2015/04/01',4
SELECT t.value,t1.value,(t.value+t1.value)/2 FROM #temp t1
left join #temp t on t.month_type=Dateadd(MONTH,-1,t1.month_type)