【问题标题】:Nested query that requires the first result to be returned需要返回第一个结果的嵌套查询
【发布时间】:2018-02-11 17:52:34
【问题描述】:

我有两张这样的桌子

表格错误代码:

type_code    desc
01           Error101
02           Error99
03           Error120 

表错误XML:

row_index     typeCode
1             87
2             02
3             01

输出应该是两个表之间第一个匹配的 type_code 的描述(列 desc)

预期输出:Error99

目前为止。

select isnull(descript, 'unknown')  as DESCRIPTION
from (select top 1 a.stmt_cd as descript
    from ErrorCodes a, ErrorXML b
    where a.type_cd = b.typecode
    order by b.row_index)

但是当两个表之间没有公共类型代码(连接条件)时,此查询不会返回字符串 UNKNOWN。在这种情况下,我得到了 null。

我该如何解决这个问题?

【问题讨论】:

    标签: sql hsqldb select-case


    【解决方案1】:

    这个怎么样:做一个子查询来为每个 type_code 带回第一个 row_index。 对 ErrorCodes 表执行 LEFT OUTER Join,这样您也可以获得 NULL。

    SELECT 
        ISNULL(ErrorCodes.desc,'unknown') AS description
        ErrorXML.row_index
    FROM ErrorCodes 
    LEFT OUTER JOIN (
                     SELECT type_code, MIN(row_index) AS row_index 
                     FROM ErrorXML
                     GROUP BY type_code
                    ) AS ErrorXML ON ErrorCodes.type_code = ErrorXML .type_code
    

    【讨论】:

      【解决方案2】:

      这是一个有趣的问题。我相信以下可以是一个直观而漂亮的解决方案(我使用desc_作为列名,而不是desc,这是一个保留字):

      select (select desc_ from ErrorCodes x where x.type_code = a.typeCode) desc_
          from ErrorXML a
          where (select desc_ from ErrorCodes x where x.type_code = a.typeCode) is not null
          order by row_index 
          limit 1;
      

      如果您还需要处理查询没有返回行的情况,那么对于 MySQL,以下语法就​​足够了。对于其他数据库,您可以使用 isnull、nvl 等类似的封装:

      select ifnull((select (select desc_ from ErrorCodes x where x.type_code = a.typeCode) desc_       from ErrorXML a       where (select desc_ from ErrorCodes x where x.type_code = a.typeCode) is not null order by row_index limit 1), 'UNKNOWN');
      

      为了测试,我使用了以下脚本并且似乎可以正常工作:

      create database if not exists stackoverflow;
      use stackoverflow;
      drop table if exists ErrorCodes;
      create table ErrorCodes
      (
          type_code varchar(2),
          desc_ varchar(10)
      );
      insert into ErrorCodes(type_code, desc_) values
          ('01', 'Error101'),
          ('02',  'Error99'),
          ('03', 'Error120');
      drop table if exists ErrorXML;
      create table ErrorXML
      (
          row_index integer,
          typeCode varchar(2)
      );
      insert into ErrorXML(row_index, typeCode) values
          ('1', '87'),
          ('2', '02'),
          ('3', '01');
      

      Final-1 引用:在生成表格时,尽量使用相同的列名。 IE。我建议ErrorXML 使用type_code 而不是typeCode

      最后引用:我选择在 SQL 中使用小写字母,因为在强调重点的同时应该使用大写字母。我也推荐这种风格。

      【讨论】:

      • 感谢您的回复。在上述查询中,如果 errorXml 的类型代码为 99、12、11。那么预期的结果应该是未知的。我怎样才能做到这一点?这就是我被困的地方
      • @keanu 请检查更新的答案。在原来的选择语句之后有一个新的选择语句。
      • 你是我今天最喜欢的人,我的朋友。这个查询很漂亮。非常感谢!
      • 然后您可以投票并接受答案。欣赏,干杯。 ;-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多