【问题标题】:A Novice SQL User Trying To Create A Complex SQL Query尝试创建复杂 SQL 查询的 SQL 新手用户
【发布时间】:2012-05-12 02:06:14
【问题描述】:

我正在尝试创建一个相当混乱的 SQL 查询,我似乎无法弄清楚它的代码。

在我的示例中,我正在查询四个表:

  1. 用户
  2. 文档
  3. 网络
  4. Network_Documents

在我的数据库中,有以下规则: 用户可以创建自己的文档 用户可以是网络的成员。他们可以选择将自己的一些文档分配给网络。文档和网络之间的链接存储在“Network_Documents”中,其中存储了 DocumentID 和 NetworkID。

我要做的是创建一个查询来检索分配给网络的所有文档。例如,假设以下是我的数据库数据:

userID userName userEmail 
  1     Adam     1@m.net 
  2     Greg     2@m.net
  3     Tony     3@m.net

docID    docName      docContents docCreator(FK)
  1     document01     dcmnt01A       1
  2     document02     dcmnt02B       2
  3     document03     dcmnt03C       3

networkID    networkName      networkCreator(FK)
   1          network01             1
   2          network02             2     
   3          network03             3

docnetID    netID(FK)   docID(FK)
    1          1           1
    2          1           3
    3          2           9999

我现在需要做的是创建一个 SELECT 查询来获取与网络关联的所有文档。例如,通过查询network01,我检索到以下两个文档。

文档网络:network01
文件名称:document01
文档创建者:Adam


文档网络:network01
文件名称:document03
文档创建者:Tony

我认为以下 SQL 查询会从特定网络中选择所有文档(及其创建者):

SELECT users.userID, users.userName,
       documents.docID, documents.docName, documents.docContents, documents.docCreator
       networks.networkID, networks.networkName, networks.networkCreator,
       network_documents.netID, network_documents.docID
FROM users, documents, networks, network_documents
WHERE networkID = 1;

上面的查询好像产生了几百!记录,它们几乎都是重复的。编写此类查询的正确方法是什么?

感谢您的帮助

【问题讨论】:

  • 你最大的问题是你没有指定你的连接标准——系统不能真正告诉你希望这些行如何相关。哦,通常最好显式声明您的JOINs,而不是像这里那样使用隐式连接语法(逗号分隔的FROM 列表);当尝试指定LEFT JOINs 时,它开始变得有趣。此外,docNetId 不是必需的 - 对 [netId, docId] 应该是唯一的。并且不要在列名前加上表名(保存,也许是 id 列),这只是噪音。

标签: mysql sql database select


【解决方案1】:

使用JOIN

SELECT  [...]
FROM    networks n
        INNER JOIN network_documents nd ON n.networkID = nd.networkID
        INNER JOIN documents d ON nd.docID = d.docID
        INNER JOIN users u ON d.docCreator = u.userID
WHERE   n.networkID = 1;

我使用别名(缩写形式)作为表名)以避免重复。您有时会看到使用 AS 关键字指定的这些内容(例如 networks as n)。

(为清楚起见省略了列列表)

【讨论】:

  • 由于是新手,我要补充的是,列规范可以使用表名的“短格式”或“别名”(例如SELECT u.userName, d.docName ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多