如何从SQL中的三个不同表中查找所有详细信息?

时间:2016-12-30 12:03:33

标签: sql sql-server

我在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结构只是为了理解。

任何人都可以给我一些帮助/提示,​​以便我可以得到提及的输出吗?

2 个答案:

答案 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。
  • 另请注意,表3中的2行与table2中的同一行匹配。因此,返回table3中的两行,并将table1和table2中的匹配数据复制到两行。