Recursive sql select from unlimited nodes - sql

I have this table in sql:
TopicID Code Name ParentID
------- ---- ---- --------
1 001 Parent1 0
2 001 Childp1 1
3 002 Parent2 0
4 001 Childp2 3
5 001 Childp21 4
.
.
etc
Now I want to
1.get sql select which retrives me the last node? (which I did by following line)
select * from accounting.topics where topicid not in(select parentid from accounting.topics)
and the result is:
TopicID Code Name ParentID | newcolumn
------- ---- ---- -------- | ---------
2 001 Childp1 1 | 001001
5 001 Childp21 4 | 002001001
2.Important one is to show the concat of code from first to last node of each row in above result,like newcolumn in above,Actually I can't produce the newcolumn ?
*notice that the nodes level are unlimited.

This could be done relatively easy with recursive common table expressions:
with cte as (
select
T1.TopicID, T1.Code, T1.Name, T1.ParentID,
T1.ParentID as NewParentID,
cast(T1.Code as nvarchar(max)) as NewColumn
from Table1 as T1
where not exists (select * from Table1 as T2 where T2.ParentID = T1.TopicID)
union all
select
c.TopicID, c.Code, c.Name, c.ParentID,
T1.ParentID as NewParentID,
c.NewColumn + cast(T1.Code as nvarchar(max)) as NewColumn
from cte as c
inner join Table1 as T1 on T1.TopicID = c.NewParentID
)
select
c.TopicID, c.Code, c.Name, c.ParentID, c.NewColumn
from cte as c
where c.NewParentID = 0
sql fiddle demo

Related

Same column name from two tables satisfying two conditions

I need some quick help on SQL. This is basic for most I am sure.
I want to select orderId in both tables merged that satisfies status = 1.
Please find example of the two table tb1 and tb2 here:
tb1
orderId status
---------------
001 0
003 1
005 1
007 1
...
tb2
orderId status
----------------
002 1
008 1
004 0
Use this query:
SELECT
tb1.OrderId,
tb1.Status
FROM
tb1
WHERE
tb1.status = 1
UNION
SELECT
tb2.OrderId,
tb2.Status
FROM
tb2
WHERE
tb2.status = 1;
You can use UNION ALL.
Your query would be:
SELECT *
FROM (
SELECT *
FROM tb1
UNION ALL
SELECT *
FROM tb2
) a
WHERE STATUS = 1

Pivot not give expected result

I m using pivot and unpivot but I dot get expected output
Here is my sample data set
Table 1
id c_code
-----------------
123 1
456 1
Table 2
id c_code i_t_code i_code
----------------------
123 1 TWinc 10
123 1 TBinc 20
123 1 TSinc 30
Table 3
i_code i_t_code i_name
------------------------------
10 TWinc abc
20 TBinc xyz
30 TSinc pqr
Here is my query
Query
select * from (
select id,inc,i_t_code from (
select a.id,b.i_name,cast(b.i_code AS
VARCHAR(128)) as i_code,b.i_t_code
from
table_1 a
join
table_2 b
on a.id= b.id
and
a.c_code = b.c_code
join
tabl_3 c on c.i_code = b.i_code
and
c.i_t_code = b.i_t_code
on a.i_code = b.i_code
) d
Unpivot
(
inc for details in (i_name,i_code)
) as unpt) as uppt_res
PIVOT
(
max(inc)
FOR [i_t_code] IN ([TWinc],[TBinc],[TSinc])
) AS P
Expected output:
id TWinc_n TWinc_c TBinc_n TBinc_c TSinc_n TSinc_c
------------------------------------------------------------
123 abc 10 xyz 20 pqr 30
Actual output:
id TWinc TBinc TSinc
------------------------------------
123 abc xyz pqr
How can do this ??
It is possible using pivot or any other solution is there
can anyone help to fix this ?
You're going to have to give your data some variation if you want to stop pivot from compressing equal data items together when it's converting row data into column names and picking the max(inc) - probably easiest to do by changing the contents of the unpivoted data, tacking on a row number:
SELECT * FROM
(
select stoneid, inc, CONCAT(inclusion_type_id, ROW_NUMBER()OVER(PARTITION BY inclusion_type_id ORDER BY inc)) as inclusion_type_id FROM
(
select
a.stoneid,
b.inclusion_name,
cast(b.inclusion_code AS VARCHAR(128)) as inclusion_code,
b.inclusion_type_id,
b.inclusion_type_code
from
PACKET.STONE_LAB_INCLUSIONS a
inner join
MASTER.INCLUSION_MASTER b
on
a.inclusion_code = b.inclusion_code and
a.inclusion_type_code = b.inclusion_type_code
inner join
packet.stone_details c
on
c.stoneid = a.stoneid and
c.certificate_code = a.certificate_code
) d
UNPIVOT(inc for details in (inclusion_name,inclusion_code)) as unpt
) uppt_res
PIVOT
(
MAX(inc)
FOR [inclusion_type_id] IN ([TWinc1],[TWinc2],[TBinc1],[TBinc2],[TSinc1],[TSinc2])
) AS P
If you're desperate to have column names the same, you can alias the results of this query rather than select *

SQL query involving 2 tables

I have 2 tables like this:
Table_1 Table_2
--------------- -------------------
id bk_title bk_no bk_isbn
--------------- ---------------------
1 A_Book 1 ISBN0001
2 B_Book 1 ISBN0002
2 ISBN0003
I want to fetch records as:
BK_Title Num_Copies
----------------------------
A_Book 2
B_Book 1
Any SQL example would be of great help for me.
This is a simple INNER JOIN and GROUP BY with a COUNT:
Select T1.bk_title, Count(*) As Num_Copies
From Table_1 T1
Join Table_2 T2 On T1.id = T2.bk_no
Group by T1.bk_title

SQL. How to select multiple rows by using the MIN and GROUP BY

ID UserId Name Amount RewardId
----------------------------
1 1 James 10.00 1
2 1 James 10.00 2
3 1 James 10.00 3
4 2 Dave 20.00 1
5 2 Dave 20.00 3
6 3 Lim 15.00 2
I'm trying to insert to another table, and this is the result that i'm struggling with:
Tbl1ID RewardId
------------------
1 1
1 2
1 3
4 1
4 3
6 2
I'm trying to get the MIN(ID) of each person and select all the RewardId that belong to that person.
You could do a simple self join to get the minimum id value per userid/rewardid combination;
SELECT MIN(a.id) Tbl1ID, b.RewardId
FROM mytable a
JOIN mytable b
ON a.name = b.name
GROUP BY b.userid, b.rewardid
ORDER BY tbl1id, rewardid;
An SQLfiddle to test with.
If you are running SQL Server 2008+, you can simplify it by using Window Function.
INSERT INTO AnotherTable (Tbl1ID, RewardID)
SELECT MIN(ID) OVER (PARTITION BY Name),
RewardID
FROM SourceTable
SQLFiddle Demo
Try this
SELECT tbl1id,RewardID From
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name FROM table1 GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id
FIDDLE DEMO
Output:
Tbl1ID RewardId
----------------
1 1
1 2
1 3
4 1
4 3
6 2
If you want insert into new table then try this out
Insert into Newtable (tbl1id,RewardID)
SELECT tbl1id,RewardID from
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name
FROM table1
GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id;
FIDDLE DEMO

Select Distinct value from column and return all rows

I'm trying to select distinct value from a column but return all rows related to the values selected. In psuedo code it will look like this.
SELECT *
FROM table
WHERE field is Distinct
I googled the question and I've tried using GROUP BY but the query never executes. Thanks for the help.
I am using a Microsoft SQL Database.
The Data looks like this:
CodeId Code CatalogType CodeGroup CodeText CodeGroupText CodeDesc State_ID
------- ----- ------------- ---------- -------- -------------- --------- ---------
1 AAAA 1 100 Plastic Plastic Center NULL 2
2 BBBB 1 100 Glass Glass Center NULL 2
3 CCCC 1 101 Steel Steel Center NULL 2
I just want to the data to look the same just where the code group is distinct.
Data would look like this:
CodeId Code CatalogType CodeGroup CodeText CodeGroupText CodeDesc State_ID
------- ----- ------------- ---------- -------- -------------- --------- ---------
1 AAAA 1 100 Plastic Plastic Center NULL 2
3 CCCC 1 101 Steel Steel Center NULL 2
You could always use a subquery to return the min(codeid) for each codegroup and join this result to your table:
select t1.codeid,
t1.code,
t1.catalogtype,
t1.codegroup,
t1.codetext,
t1.codegrouptext,
t1.codedesc,
t1.state_id
from yourtable t1
inner join
(
select MIN(codeid) codeid, codegroup
from yourtable
group by codegroup
) t2
on t1.codeid = t2.codeid
and t1.codegroup = t2.codegroup
In most databases, you can do:
select t.*
from (select t.*
row_number() over (partition by field order by field) as seqnum
from t
) t
where seqnum = 1
SELECT field1,field2,max(field3),sum(field4)
FROM table
GROUP BY field1, field2
This will give you all distinct field1 and field2's. You cannot get the field3 field directly (with this grouping), since there may be multiple field3's.
if you need just distinct values from a column, i.e. to find a set of unique values in one column, then this code helps you (for sql server at least):
select distinct
columnName
from tableT