我在sql中有三个不同的表。以下是表格结构。
Table1:
pId - primary key
pName
Table2:
sId - primary key
sName
pId- foreign key
Table3:
gId primary key
gName
sId - Foreign key
table1和table2之间的关系是1到多,table2到table3再次是1到多。
现在我希望table1和table3中的所有数据都用于table1中的每个pId。
我尝试了以下查询:
select p.pId, p.pName, s.sId, s.sName, g.gId, g.gName
from table1 as p,
table2 as s,
table3 as g
where p.pId=s.pId AND s.sId=g.sId
group by p.pId;
table1的示例数据:
pId pName 1 p1 2 p2
table2的示例数据:
sId sName pId 11 s1 1 12 s1 2
table3的示例数据:
sId gId gName 11 111 g1 11 112 g2
我想输出如下内容:
[{pId:1,
pname:p1,
sub:[{
sId:11,
sName:s1,
grades:[{
gId:111,
gName:g1
},{
gId:112,
gName:g2
}]
}]
},
pId:1,
pname:p1,
sub:[{
sId:12,
sName:s2,
grades:[]
}]
}]
Json结构只是为了理解。
任何人都可以给我一些帮助/提示,以便我可以得到提及的输出吗?
答案 0 :(得分:2)
当前的select语句应该引发错误,因为在使用group by时,select子句中只存在group by子句或aggrigation函数中存在的列。
正确的查询非常类似于您发布的查询,只是没有组和正确的显式连接(隐式连接已经过时了20多年),并将这些连接转换为左连接:
SELECT p.pId, p.pName, s.sId, s.sName, g.gId, g.gName
FROM table1 as p,
LEFT JOIN table2 as s ON p.pId=s.pId
LEFT JOIN table3 as g ON s.sId=g.sId
这应该会得到以下输出:
pId pName sId sName gId gName
1 p1 11 s1 111 g1
1 p1 11 s1 112 g2
2 p2 12 s1 null null
答案 1 :(得分:1)
如果删除GROUP BY
部分,您现有的查询就可以了。但是,我强烈建议您在JOIN
子句中使用明确的FROM
子句。它使得更容易:将连接条件与过滤条件区分开来;发现你的联接中的错误;更清楚地阅读所使用的连接类型(INNER或LEFT / RIGHT / FULL OUTER)。
E.g。
select p.pId, p.pName, s.sId, s.sName, g.gId, g.gName
from table1 as p
inner join table2 as s ON
s.pId = p.pId
inner join table3 as g ON
g.sId = s.sId
这将产生下表:
pId pName sId sName gId gName 1 p1 11 s1 111 g1 1 p1 11 s1 112 g2
或者,您可以将inner join
替换为left outer join
以观察输出中的以下更改:
pId pName sId sName gId gName 1 p1 11 s1 111 g1 1 p1 11 s1 112 g2 2 p2 12 s1 NULL NULL
差异如下:
inner join
要求在联接的两边进行匹配。因为table3与table2中的sId=12
不匹配,所以它被排除在外。pId=2
不再与其加入匹配,也会被排除。left outer join
表示左手边不需要匹配。因此,包含了行,但由于table3中没有匹配的行,因此这些值将返回为NULL。