【问题标题】:How to find all details from three different tables in SQL?如何从 SQL 中的三个不同表中查找所有详细信息?
【发布时间】:2016-12-30 12:03:32
【问题描述】:

我在 sql 中有三个不同的表。以下是表结构。

Table1:
pId - primary key
pName

Table2:
sId - primary key
sName
pId- foreign key

Table3:
gId primary key
gName 
sId - Foreign key

table1 和 table2 之间的关系是一对多,而 table2 和 table3 又是一对多。

现在我想要 table1 中每个 pId 的 table2 和 table3 中的所有数据。

我尝试了以下查询:

 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 克1 11 112克2

我想输出如下内容:

[{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 结构仅供理解。

谁能给我一些帮助/提示,​​以便我可以得到提到的输出?

【问题讨论】:

  • 剥离群组
  • (1) 用您真正使用的数据库标记您的问题。 (2) 以 SQL 格式提供样本数据和所需的输出,即作为表格。
  • “Json 结构只是为了理解”是什么意思?您是说您实际上并不想要 JSON 输出吗?请注意,关系数据库通常以行和列的形式工作。虽然某些 RDBMS 可能提供与 XML 或 JSON 相互转换的方法,但这并不是使用这些工具的自然方式。
  • @CraigYoung 我是 sql 新手,所以我提到了我想要的 Json 格式的输出。我不希望导出输出为 Json。
  • 如果您不期望 Json 格式,请提供表格格式的输出

标签: sql sql-server


【解决方案1】:

您当前的 select 语句应该会引发错误,因为在使用 group by 时,只有存在于 group by 子句或聚合函数中的列也可以存在于 select 子句中。

正确的查询与您发布的查询非常相似,只是没有 group by 并具有适当的显式联接(隐式联接现在已经过时 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

【讨论】:

    【解决方案2】:

    如果您删除 GROUP BY 部分,您现有的查询会很好。但是,我强烈建议您在 FROM 子句中使用显式的 JOIN 子句。它更容易: 区分连接条件和过滤条件;发现连接中的错误;更清楚地阅读所使用的连接类型(INNER 或 LEFT/RIGHT/FULL OUTER)。

    例如

    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 joins 替换为left outer joins 以观察输出的以下变化:

    pId pName sId sName gId gName 1 p1 11 s1 111 g1 1 p1 11 s1 112 g2 2 p2 12 s1 无 无

    区别如下:

    • inner join 要求连接两边都匹配。因此,由于 table3 没有与 table2 中的 sId=12 匹配,因此将其排除在外。
    • 同样,由于上一点,pId=2 不再有匹配的连接并被排除在外。
    • 相反,left outer join 表示左侧不需要匹配。结果,该行被包括在内,但由于 table3 中没有匹配的行,这些值将返回为 NULL。
    • 另请注意,表 3 中的 2 行与表 2 中的同一行匹配。结果,table3 中的两行都被返回,table1 和 table2 中的匹配数据被复制到这两行。

    【讨论】:

      猜你喜欢
      • 2015-12-02
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多