【问题标题】:Inner join 2 tables into one内联2表合二为一
【发布时间】:2018-04-02 15:46:00
【问题描述】:

我有 2 张桌子,试图将 inner join 放入一张桌子。我正在使用 Excel 进行查询,因此它的语法有限(Jet Access)。 stack1stack2 表是相同的,并且位于两个不同的 Excel 工作表中。

这些表来自 Vertica(stack1stack2)和 SQL Server(overflow),然后我正在尝试使用内部查询来组合这些表。

这是我尝试过的,我遇到了语法错误,不知道哪里出错了:

select *
from [stack1$], [stack2$]
INNER JOIN [overflow$]
ON [stack1$].[iddate] = [overflow$].[iddate]
AND [stack1$].[idbusiness] = [overflow$].[idbusiness]
AND [stack2$].[iddate] = [overflow$].[iddate]
AND [stack2$].[idbusiness] = [overflow$].[idbusiness]

如果我像这样只做一张桌子,它就可以正常工作:

select *
from [stack1$]
INNER JOIN [overflow$]
ON [stack1$].[iddate] = [overflow$].[iddate]
AND [stack1$].[idbusiness] = [overflow$].[idbusiness]

样本数据:

溢出:

 +----------+------------+---------+
|  iddate  | idbusiness | otherid |
+----------+------------+---------+
| 20180209 |   95971462 |    5235 |
+----------+------------+---------+

堆栈 1:

+------------+-------+----------+
| idbusiness | value |  iddate  |
+------------+-------+----------+
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 |       | 20180209 |
|   95971462 | 10.04 | 20180209 |
+------------+-------+----------+

上面的查询给了我:

+--------------------+-------+----------------+---------+
| stack1$.idbusiness | value | stack1$.iddate | otherid |
+--------------------+-------+----------------+---------+
|           95971462 |       |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
|           95971462 | 10.04 |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
|           95971462 |       |       20180209 |    5235 |
+--------------------+-------+----------------+---------+

现在我想在其中添加Stack 2,它将包含与stack1 相同的列,但与idbusiness 不同,然后在stack1 中。看起来也不需要iddate,所有记录都是相同的日期。

【问题讨论】:

  • 底层数据库是什么?
  • @GordonLinoff ,这些表来自 Vertica(堆栈 1 和堆栈 2)和 SQL Server(溢出)然后我正在尝试内部查询来组合这些表。

标签: sql sql-server vertica jet


【解决方案1】:

试试Union,它会给你(overflow$ join stack1$) union (overflow$ join stack2)的唯一行。

SELECT * FROM [overflow$]
JOIN [stack1$]
ON [stack1$].[iddate] = [overflow$].[iddate]
AND [stack1$].[idbusiness] = [overflow$].[idbusiness]
        UNION 
SELECT * FROM [overflow$]
JOIN [stack2$]
ON [stack2$].[iddate] = [overflow$].[iddate]
AND [stack2$].[idbusiness] = [overflow$].[idbusiness]

【讨论】:

    【解决方案2】:

    就像 Gordon 所说,不建议在同一个查询中混合使用隐式和显式连接。以下是使用隐式连接编写查询的方式:

    SELECT *
    FROM [overflow$], [stack1$], [stack2$]
    WHERE [stack1$].[iddate] = [overflow$].[iddate]
      AND [stack1$].[idbusiness] = [overflow$].[idbusiness]
      AND [stack2$].[iddate] = [overflow$].[iddate]
      AND [stack2$].[idbusiness] = [overflow$].[idbusiness]
    

    为了完整起见,以下是使用显式连接编写查询的方式(如 Gordon 的回答,但使用您的命名风格):

    SELECT *
    FROM ([overflow$]
          INNER JOIN [stack1$]
                  ON [stack1$].[iddate] = [overflow$].[iddate]
                 AND [stack1$].[idbusiness] = [overflow$].[idbusiness])
    INNER JOIN [stack2$]
            ON [stack2$].[iddate] = [overflow$].[iddate]
           AND [stack2$].[idbusiness] = [overflow$].[idbusiness]
    

    通常建议使用显式连接。遗憾的是,Jet 语法需要括号来连接,这使得编写和阅读变得更加困难。

    如果这些条件是正确的,那么上面的两个查询应该是相同的并且给你相同的结果。但是,某些数据库存在隐式连接的问题/错误,因此结果(主要是性能)可能会有所不同。我不知道 Vertica,但对于最新版本的 SQL Server,应该没有区别。

    如果您没有从上述查询中获取记录,那么条件可能是错误的。我怀疑您实际上想要结合UNION 的两个查询的结果:

    SELECT *
    FROM [overflow$]
    INNER JOIN [stack1$]
            ON [stack1$].[iddate] = [overflow$].[iddate]
           AND [stack1$].[idbusiness] = [overflow$].[idbusiness]
    UNION ALL
    SELECT *
    FROM [overflow$]
    INNER JOIN [stack2$]
            ON [stack2$].[iddate] = [overflow$].[iddate]
           AND [stack2$].[idbusiness] = [overflow$].[idbusiness]
    

    【讨论】:

    • 您的联合查询似乎使我的 excel 崩溃或需要很长时间。上面的其他人快速返回,但 0 结果只是标题。我已经发布了一些示例数据。
    • 如果您在问题中提到的单独使用[stack1$] 进行查询,您会得到多少条记录?如果你用[stack2$] 做呢?如果这两个单独的查询返回合理数量的记录(几百或几千),那么UNION 应该可以正常运行。您可以尝试使用UNION 而不是UNION ALL,但这会消除所有重复记录,因此这取决于您想要的结果。
    • overflow 有 5k 条记录,stack1 有 950k 条记录。加入他们的结果得到大约 250k 条记录,但需要 10 分钟。我认为这与大小有关,stack2 我什至不能自己运行,但是当我缩小它时,它会很好地查询。我将不得不缩小我认为然后加入的数据集。
    • 这显然是问题所在,如果您甚至无法单独运行stack2,那么您将无法使用UNION 添加它。即使你缩小它,如果它在 10 分钟内产生 250k 类似于stack1,那么 UNION 将在大约 20 分钟内产生 500k。好多啊。您可以收缩数据,但更重要的是您需要在所有 3 个表中的 [iddate][idbusiness] 列上创建索引。对于完整的UNION 查询,这应该会将时间显着减少到大约一两分钟。
    • 创建索引是什么意思?我该怎么做?
    【解决方案3】:

    不要混合使用旧式和新式连接。

    这样的事情应该可以工作:

    select *
    from ([overflow$] as o inner join
          [stack1$] as s1
          on s1.[iddate] = o.[iddate] and
             s1.[idbusiness] = o.[idbusiness]
         ) inner join
         [stack2$] as s2
         on s2.[iddate] = o.[iddate] and
            s2.[idbusiness] = o.[idbusiness];
    

    我使用 MS Access 语法编写了这个。其他数据库中不需要括号。

    【讨论】:

    • “旧式”连接的技术术语是“完全连接”(也称为“交叉连接”)。如果为连接条件添加WHERE 子句,则称为“等连接”。在比较“旧式”和“新式”时,我们通常将它们称为“隐式连接”与“显式连接”。
    • @GordonLinoff ,谢谢您的回答,您提供的查询有效,没有错误,但没有值,但我确实返回了标题。当我进行单表连接时(如上所示),我确实返回了记录。
    • 如果您没有获得任何记录,那么您使用的条件不正确。发布 3 个表的一些示例数据和您的预期输出,以便我们更好地帮助您,否则我们无法判断正确的条件必须是什么。
    • @RacilHilan,我已经发布了一些示例数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多