【问题标题】:SQL Union not working when one table is empty当一个表为空时,SQL Union 不起作用
【发布时间】:2021-02-04 12:47:56
【问题描述】:

您好,我正在尝试使用 SELECT 语句从不同的表中读取数据,并希望最终使用 UNION 来获取一个数据集。一个表可能(还)不包含数据。在这种情况下,我可以成功读取前两个数据集的数据,但是一旦我使用 UNION 将其与空表中的数据结合起来,结果数据集也将为空,即使它之前包含前两个数据集的数据。

我的问题是,数据在这些表之间不规则地移动,所以我无法知道我会在三个表中的哪一个中找到数据,而且在任何情况下,我通常必须将多个表的结果组合到获取我需要的整个数据集(一个包含仅 3 个月前的数据,另外两个包含去年和当前年份的数据 - 取决于我需要数据的时间段,因为我可能必须查看所有三个他们收集我需要的所有数据)。

您知道如何检查所有三个表并读取数据以收集我需要的整个数据集吗? 我还测试了是否一切正常,以防所有三个表都包含数据,等等,它工作了,我检索了我需要的所有数据。所以语句本身应该没问题,只是不适用于一张表不包含数据的特殊情况。

我正在使用 Python 连接数据库并通过 sql 语句检索数据。

所以我的sql语句目前是这样的:

        sql_stmt = (
            "select " + sql_param+" from " + db_table +
            " where datum>=" + season_start_sql + " and datum<" + season_end_sql +
            " and statnr="+str(statnr) +
            " union" +
            " select " + sql_param+" from " + db_table +
            " where datum=" + season_end_sql + " and stdmin<=" + season_end_time_sql +
            " and statnr="+str(statnr) +
            " union" +
            " select " + sql_param + " from " + db_table + "_" + str(season_start.year) +
            " where datum>=" + season_start_sql + " and datum<" + season_end_sql +
            " and statnr=" + str(statnr) +
            " union" +
            " select " + sql_param + " from " + db_table + "_" + str(season_start.year) +
            " where datum=" + season_end_sql + " and stdmin<=" + season_end_time_sql +
            " and statnr=" + str(statnr) +
            " union" +
            " select " + sql_param + " from " + db_table + "_" + str(next_year) +
            " where datum>=" + season_start_sql + " and datum<" + season_end_sql + 
            " and statnr=" + str(statnr) +
            " union" +
            " select " + sql_param + " from " + db_table + "_" + str(next_year) +
            " where datum=" + season_end_sql + " and stdmin<=" + season_end_time_sql +
            " and statnr=" + str(statnr) +
            " order by datumsec")

【问题讨论】:

  • UNION的两个表中的一个为空也没关系,你仍然会从另一个表中获取数据。
  • 我相当怀疑您使用字符串连接将值输入查询会增加一些流氓值,而整个查询实际上会出错。使用参数化查询。您可能还需要修改架构。好像你每年都有一张桌子。不要那样做,所有年份都有一个,并在额外的列中表示年份。为什么UNION 呢?这是出于性能原因吗?因为在WHERE 子句中使用OR 可以更简单地表达它。
  • 好的,谢谢。 Unforutnatley 我无法更改表的架构。我不负责数据库,而只是使用其中的数据。另外,如果我理解正确并且 OR 不会导致数据集包含所有表中的数据......?有可能我需要从他们每个人那里读取数据确实收集了我需要的整个数据集。
  • 好的,我忽略了实际上涉及三个表。所以你需要UNION他们的结果。但是,如果您在 WHERE 子句中使用 OR,则每个表只需要一个查询。
  • 您的 DBMS 是什么?也许它有一些可能通过Google BigQuery中的模式查询表。

标签: sql union


【解决方案1】:

这种说法根本不正确:

一旦我使用 UNION 将它与空表中的数据结合起来,结果数据集也将为空,即使它包含之前前两个数据集的数据。

如果UNION 的组件之一为空,那么您仍会从其他表中获得结果。

注意:如果其中一个表不存在——这与空表完全不同——则查询返回错误,但不是空结果。

我会注意到,通常您应该使用UNION ALL 而不是UNION,以避免删除重复值的开销。而且您的代码很容易受到 SQL 注入攻击和意外语法错误的影响。我会质疑您的应用程序是否可以设计为不必为此目的使用动态 SQL。

【讨论】:

  • 感谢您的快速回复...如您所见,我是 sql 新手,可能找不到根本问题。我所知道的是,仅使用前三个 select 语句才有效,我检索数据,添加后三个,每个调用一个当前不包含请求的“数据”数据的表,使我检索一个空数据集。但是,所有这些表都存在,并且如果一个表不存在,我也会捕获返回的错误。在这种情况下,我创建了一个新的 sql 语句,而没有丢失表的 select 语句
  • @vroni - 尝试调试您的代码以找到实际正在执行的确切字符串,或者只是添加一个打印语句来获取它。然后在 SQL 客户端 (例如 SQL Server Management Studio、MySQL Workbench 或任何最适合您的工具)中运行该 SQL 代码
  • @MatBailie 感谢您的评论,是的,我将尝试再次调试代码...但是在不同的时期内使用完全相同的 sql 语句测试完全相同的代码,我知道所有表包含我需要的一些数据之前工作得很好......但我想我一定错过了什么
  • @Vroni 如果它在一个时期有效,但在另一时期无效,则需要获取没有的 exact sql 代码不行。做假设是没有意义的。让 python 编写 SQL,提取它,并从 python(在 SQL 客户端中)单独调试该 SQL。如果您发现 SQL 包含错误,您可以然后尝试找出 python 生成带有该错误的 SQL 的原因...
  • @MatBailie 好的,是的,我想我将不得不再次调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 2019-07-06
相关资源
最近更新 更多