I Have a SQL server 2008 Database. I have a table with the following structure
CatID ParentCatID NAME Level
1 NULL A 1
2 1 B 2
3 2 C 3
4 NULL D 1
5 4 E 2
6 5 F 3
7 NULL G 1
8 7 H 2
I want to Select the Name column in Heirarchical format like below:
Level1 Level2 Level3
A B C
D E F
In my Table all level1 categories have level2 children. Similarly all level2 children have level3 children. So how can i get the data in my desired format.
It's a simple query like this:
select
C1.NAME as Level1,
C2.NAME as Level2,
C3.NAME as Level3
from Categories C1
inner join Categories C2
on C2.ParentCatId = C1.CatId
inner join Categories C3
on C3.ParentCatId = C2.CatId
where C1.Level = 1 and C2.Level = 2 and C3.Level = 3 and
Related
I have three tables: users, products and reviews. I'm trying to get form a table that would show products that have gotten the same review from different users, the users who reviewed it and what review it got.
Here are the tables and the output I'm looking for:
Users
uid uname
1 name1
2 name2
3 name3
4 name4
Products
pid pname
1 A
2 B
3 C
4 D
Reviews
pid uid grade
1 1 3
1 2 2
1 3 3
2 1 4
3 2 1
2 2 4
4 3 1
Desired output:
uname uname2 pname grade
name1 name3 A 3
name3 name1 A 3
name1 name2 B 4
name2 name1 B 4
There are some overly complicated answers here.
Its pretty simple using a self join like this:
select u1.uname, u2.uname, p.pname, r1.grade
from review r1
join review r2 on r2.pid=r1.pid and r2.grade=r1.grade and r2.uid<>r1.uid
join products p on p.pid=r1.pid
join users u1 on u1.uid=r1.uid
join users u2 on u2.uid=r2.uid
order by pname, r1.grade, u1.uname, u2.uname
Result:
uname uname1 pname grade
name1 name3 A 3
name3 name1 A 3
name1 name2 B 4
name2 name1 B 4
select users.uname, reviews.grade, products.pname from products
join reviews on products.id = reviews.pid
join users on users.id = reviews.id
This can be done using a self-join like this -
with combined as
(select (select uname from users where uid = r.uid),
(select pname from products where pid = r.pid),
r.grade,
r.uid
from reviews r)
select c1.uname as name1, c2.uname as name2, c1.pname, c1.grade
from combined c1, combined c2
where c1.grade = c2.grade
and c1.pname = c2.pname
and c1.uid <> c2.uid;
I have the following table IDDetails:
ID1 ID2 ID3
1 2 3
1 5 7 and so on
I want to link each ID of the row with a name from the Names table:
ID Name
1 A
2 B
3 C
4 D
5 E
7 G
The output should have 6 columns like :
ID1 Name1 ID2 Name2 ID3 Name3
1 A 2 B 3 C
1 A 5 E 7 G
The operation should have minimum joins with limited cost.
This query will give you the results you want. Note that you have to JOIN the Names table 3 times to get the three different names for each row.
SELECT i.ID1, n1.Name AS Name1,
i.ID2, n2.Name AS Name2,
i.ID3, n3.Name AS Name3
FROM IDDetails i
JOIN Names n1 on n1.ID = i.ID1
JOIN Names n2 on n2.ID = i.ID2
JOIN Names n3 on n3.ID = i.ID3
Output:
ID1 Name1 ID2 Name2 ID3 Name3
1 A 2 B 3 C
1 A 5 E 7 G
Update
Here is a query without JOINs, as requested in the edit after the original post:
SELECT i.ID1, (SELECT Name FROM Names n WHERE n.ID = i.ID1) AS Name1,
i.ID2, (SELECT Name FROM Names n WHERE n.ID = i.ID2) AS Name2,
i.ID3, (SELECT Name FROM Names n WHERE n.ID = i.ID3) AS Name3
FROM IDDetails i
Output:
ID1 Name1 ID2 Name2 ID3 Name3
1 A 2 B 3 C
1 A 5 E 7 G
SQLFiddle Demo of both queries
I only have 1 table called Posts with 5 columns (much like StackExchange Data Explorer)
Id, Score, PostTypeId, ParentId, AcceptedAnswerId
1 5 1 null 3
2 3 1 null 5
3 9 2 1 null
4 3 2 1 null
....
As you can see, the rows have two levels of hierarchy (Parents, Childs). Let's say I want to select the childs (PostTypeId = 2) and for each one I would like to left join the score of the sibling that is currently accepted by the parent. The accepted sibling Id can only be found in the AcceptedAnswerId column of the parent row. The parent row can be found through the ParentId of the child row I am selecting. Is there an elegant way to do this?
The expected results is the following
Id, Score, AcceptedScore
3 9 9
4 3 9
....
My attempt (although it doesn't work and hurts my eyes as well as my brain):
select top 50 a.Id, a.Score, b.Score as AcceptedScore
from Posts as a
left join (
select c.Score from Posts as c
where c.Id = (
select d.AcceptedAnswerId from Posts as d
where d.Id = a.ParentId
)
) as b
on b.ParentId = a.ParentId
where a.PostTypeId = 2
The error I'm getting:
The multi-part identifier "a.ParentId" could not be bound. Invalid column name 'ParentId'.
Here's one that works:
SELECT p1.Id, p1.Score, p3.Score AS AcceptedScore
FROM Posts p1 LEFT JOIN Posts p2
ON p1.ParentId = p2.Id LEFT JOIN Posts p3
ON p2.AcceptedAnswerId = p3.Id
WHERE p1.PostTypeId = 2
See the SQLFiddle
I have an example where in a table there is ID,NAme and M_if(managerID). I populated the table in the following manner
Id Name M_id
1 A 2
2 B NUll
3 C 1
4 D 3
5 E 2
Id is employee ID, Name and M_id is manager ID. In above example A's manager is 2(B), B doesn't have manager, C's manager is 1(A) and so on. I need to find out the names of the employees and their managers name. I have written the following query by doing permutations and combinations which gives me proper result but I am not able to comprehend how exactly the query(left join) is working. Please make me explain the concept.
SELECT (e.Name), ee.name FROM test.employee e
left join test.employee ee on ee.Id = e.M_id
order by e.Id;
result i get
A B
B
C A
D C
E B
Please explain me the joint
two instances are there for same table as :
e
Id Name M_id
1 A 2
2 B NUll
3 C 1
4 D 3
5 E 2
ee
Id Name M_id
1 A 2
2 B NUll
3 C 1
4 D 3
5 E 2
according to your join condition on ee.Id = e.M_id
simply first row of instance e will be selected because of left join and e.M_id will get compared to ee.Id and 2nd row will be selected from second instance of same table.
selection of data from both the table is as :
e.Id e.Name e.M_id | ee.Id ee.Name ee.M_id
1 A 2 | 2 B NUll
2 B NUll |
3 C 1 | 1 A 2
4 D 3 | 3 C 1
5 E 2 | 2 B NUll
that is why it is showing
A B
I have two tables
Tab1
id Name Level
1 a1 1
2 a2 1
3 b1 2
4 b2 2
5 c1 3
6 c2 3
7 b3 2
8 c3 3
9 c4 3
Tab2
id linkid
1 3
3 6
1 7
7 8
3 9
I am trying to fetch different levels of id which falls for level = 1
something like
Tab3
Level1 Level2 Level3
1 3 6
1 7 8
1 3 9
Can anyone help me?
Following statement is sufficient for the data you've presented ...
SQL Statement
SELECT lvl1.id AS Level1
, lvl2.id AS Level2
, lvl3.id AS Level3
FROM Tab2 lvl1
INNER JOIN Tab2 lvl2 ON lvl2.id = lvl1.linkid
INNER JOIN Tab2 lvl3 ON lvl3.id = lvl2.linkid
WHERE lvl1.id = 1
... but I assume you somehow need Tab1 incorporated into the results so this might be closer to what you really require
SQL Statement
SELECT lvl1.id AS Level1
, lvl2.id AS Level2
, lvl3.id AS Level3
FROM Tab1 t1
INNER JOIN Tab2 lvl1 ON lvl1.id = t1.id
INNER JOIN Tab2 lvl2 ON lvl2.id = lvl1.linkid
INNER JOIN Tab2 lvl3 ON lvl3.id = lvl2.linkid
WHERE t1.id = 1
note that I assume Tab2.id being a foreign key to Tab1.id