【问题标题】:Return results from multiple tables从多个表返回结果
【发布时间】:2014-11-12 15:44:12
【问题描述】:

我正在对 Stack Overflow 转储进行分析。

问题说明:我有 4 个表格,需要给定格式的结果。

Table 1: UserID Year QuestionsOnTopicA
Table 2: UserID Year AnswersOnTopicA
Table 3: UserID Year QuestionsOnTopicB
Table 4: UserID Year AnswersOnTopicB

期望的输出:

UserID Year QuestionsOnTopicA AnswersOnTopicA QuestionsOnTopicB AnswersOnTopicB

UserID 列应该包含来自所有 4 个表的条目。

我尝试对表执行内部和外部联接,但结果不正确。 内连接(返回仅存在于第一个表 1 中的用户 ID) 外连接(仅返回表 1 中用户 ID 的其他列)

不确定联合在这种情况下是否有意义。

正在 data.stackexchange.com/stackoverflow 上执行查询

例子

表 1:1001、2010、5 || 1001, 2011, 3 || 1002, 2010, 4

表2:1001、2010、10 || 1001, 2011, 7 || 1002, 2010, 5

表3:1002、2010、5

表 4:1001、2010、10 || 1004, 2011, 5

输出:

1001, 2010, 5 , 10, 0, 10

1001, 2011, 3, 7, 0, 0

1002, 2010, 4, 5, 5, 0

1004, 2011, 0, 0, 0, 5

【问题讨论】:

  • 我的第一反应是质疑为什么您有两组表格 (Q/A),而它们之间的所有差异都是主题。您真的想为每个主题创建一组新的表格吗?修复您的设计,您的问题就会消失。

标签: sql database join data.stackexchange.com


【解决方案1】:

好的,这按预期工作:

SELECT  COALESCE(A.UserID,B.UserID,C.UserID,D.UserID) UserID,
        COALESCE(A.[Year],B.[Year],C.[Year],D.[Year]) [Year],
        ISNULL(A.QuestionsOnTopicA,0) QuestionsOnTopicA,
        ISNULL(B.AnswersOnTopicA,0) AnswersOnTopicA,
        ISNULL(C.QuestionsOnTopicB,0) QuestionsOnTopicB,
        ISNULL(D.AnswersOnTopicB,0) AnswersOnTopicB
FROM Table1 A
FULL JOIN Table2 B
    ON A.UserID = B.UserID
    AND A.[Year] = B.[Year]
FULL JOIN Table3 C
    ON COALESCE(A.UserID,B.UserID) = C.UserID
    AND COALESCE(A.[Year],B.[Year]) = C.[Year]
FULL JOIN Table4 D
    ON COALESCE(A.UserID,B.UserID,C.UserID) = D.UserID
    AND COALESCE(A.[Year],B.[Year],C.[Year]) = D.[Year]

Here is a sqlfiddle 有一个演示。

结果是:

╔════════╦══════╦═══════════════════╦═════════════════╦═══════════════════╦═════════════════╗
║ UserID ║ Year ║ QuestionsOnTopicA ║ AnswersOnTopicA ║ QuestionsOnTopicB ║ AnswersOnTopicB ║
╠════════╬══════╬═══════════════════╬═════════════════╬═══════════════════╬═════════════════╣
║   1001 ║ 2010 ║                 5 ║              10 ║                 0 ║              10 ║
║   1001 ║ 2011 ║                 3 ║               7 ║                 0 ║               0 ║
║   1002 ║ 2010 ║                 4 ║               5 ║                 5 ║               0 ║
║   1004 ║ 2011 ║                 0 ║               0 ║                 0 ║               5 ║
╚════════╩══════╩═══════════════════╩═════════════════╩═══════════════════╩═════════════════╝

【讨论】:

    【解决方案2】:

    用这个SQL可能是什么?

    SELECT a.UserID, a.Year,
           a.QuestionsOnTopicA,
           b.AnswersOnTopicA,
           c.QuestionsOnTopicB,
           d.AnswersOnTopicB
    FROM Table 1 a,
         Table 2 b,
         Table 3 c,
         Table 4 d
    WHERE a.UserID = b.UserID
      AND b.UserID = c.UserID
      AND c.UserID = d.UserID
      AND d.UserID = a.UserID
    

    【讨论】:

    • data.SE 使用 SQL Server,因此不需要反引号
    • 好吧,现在你需要用[] 括起来你的表格
    • @PraveenKumar 谢谢。我尝试执行您的查询,但它返回所有表中都存在的 USERID 行。 (因此会跳过仅出现在某些表中的其他用户。)
    • @MohitJain 你是怎么执行的?
    • 我按原样复制了查询并更改了所需的列名。我正在 data.stackexchange.com 上运行查询
    【解决方案3】:
    select coalesce(a.UserID, b.UserID, c.UserID, d.UserID),
           coalesce(a.Year, b.Year, c.Year, d.Year),
           a.QuestionsOnTopicA, b.AnswersOnTopicA,
           c.QuestionsOnTopicB, d.AnswersOnTopicB
    from Table1 a full outer join Table2 b on a.UserID = b.UserID and a.Year = b.Year
                  full outer join Table3 c on (c.UserID = b.UserID or c.UserID = a.UserID) 
                                              and (c.Year = b.Year or c.Year = a.Year)
                  full outer join Table4 d on (d.UserID = c.UserID or d.UserID = b.UserID or d.UserID = a.UserID) 
                                              and (d.Year = a.Year or d.Year = b.Year or d.Year = a.Year);
    

    【讨论】:

    • 这看起来很有希望,但是 data.stackexchange 给出了超时过期错误-“在操作完成之前超时时间已过或服务器没有响应。”过段时间我会再试的。
    【解决方案4】:

    首先,您应该使用内连接从表中检索数据。 然后您应该使用 SQL Server Pivot,如 link 所示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多