DB2在将3个级别深入到子查询后,会失去对表的跟踪

DB2在将3个级别深入到子查询后,会失去对表的跟踪,db2,subquery,Db2,Subquery,使用此标准作者/书籍设置: CREATE TABLE authors ( id int NOT NULL, name varchar(255) NOT NULL ) CREATE TABLE books ( id int NOT NULL, name varchar(255) NOT NULL, author_id int NOT NULL, sold int NOT NULL ) INSERT INTO authors VALUES (1,

使用此标准作者/书籍设置:

CREATE TABLE authors (
    id int NOT NULL,
    name varchar(255) NOT NULL
)

CREATE TABLE books (
    id int NOT NULL,
    name varchar(255) NOT NULL,
    author_id int NOT NULL,
    sold int NOT NULL
)

INSERT INTO authors VALUES (1, 'author 1')
INSERT INTO authors VALUES (2, 'author 2')

INSERT INTO books VALUES (1, 'book 1', 1, 10)
INSERT INTO books VALUES (2, 'book 2', 1, 5)
INSERT INTO books VALUES (3, 'book 3', 2, 7)
此查询不知何故不起作用:

SELECT
    (
        SELECT
            count(*)
        FROM
            (
                SELECT
                    books.name
                FROM
                    books
                WHERE
                    books.author_id = authors.id
                    AND books.sold > (
                        SELECT
                            avg(sold)
                        FROM
                            books
                        WHERE
                            books.author_id <> authors.id
                    )
            ) AS t
    ) AS good_selling_books
FROM
    authors
WHERE
    authors.id = 1
错误消息是:

SQL0204N AUTHORS.ID是一个未定义的名称。SQLSTATE=42704

看起来DB2在深入到子查询的3个级别后,会失去对最外层表的跟踪


注意:这只是一个捏造的查询,所以它可能没有多大意义,并且可以很容易地重写为只有2层嵌套,这很好。我只想确认DB2是否确实存在这样一个明显的缺点。

问题在于最内部的查询。
如果FROM子句中没有作者,则不能仅与authors.id进行比较。

问题在于最内部的查询。
在FROM子句中没有作者的情况下,不能仅与authors.id进行比较。

这在MySQL中也会失败,并出现完全相同的错误:

ERROR 1054 (42S22): Unknown column 'authors.id' in 'where clause'
我怀疑这个问题确实不正确。我认为您需要在最内部查询的FROM子句中引用authors表。我最近做了很多NOSQL方面的工作,所以我的SQL查询技能有点落后,但我很确定,内部查询无法扩展到其他表


如果可以,请使用联接而不是嵌套查询重写查询。嵌套查询的性能往往优化得很差,在DB2中没有得到证实,但至少在MySQL 5.1中是如此。

这在MySQL中也会失败,出现完全相同的错误:

ERROR 1054 (42S22): Unknown column 'authors.id' in 'where clause'
我怀疑这个问题确实不正确。我认为您需要在最内部查询的FROM子句中引用authors表。我最近做了很多NOSQL方面的工作,所以我的SQL查询技能有点落后,但我很确定,内部查询无法扩展到其他表


如果可以,请使用联接而不是嵌套查询重写查询。嵌套查询的性能往往优化得很差,在DB2中没有得到证实,但至少在MySQL 5.1中是如此。

刚刚找到了一个相当简单的解决方案。DB2有这样一个横向关键字,这是此类查询工作所必需的,例如

SELECT
    (
        SELECT
            count(*)
        FROM
            LATERAL( -- this is the only change
                SELECT
                    books.name
                FROM
                    books
                WHERE
                    books.author_id = authors.id
                    AND books.sold > (
                        SELECT
                            avg(sold)
                        FROM
                            books
                        WHERE
                            books.author_id <> authors.id
                    )
            ) AS t
    ) AS good_selling_books
FROM
    authors
WHERE
    authors.id = 1
解决方案来自这篇博文,作者在博文中还注意到了DB2中的相同缺点:

但是DB2也没有将两个级别提升到S.c1。我想它可以,但是,唉,它没有


刚刚找到了一个相当简单的解决方案。DB2有这样一个横向关键字,这是此类查询工作所必需的,例如

SELECT
    (
        SELECT
            count(*)
        FROM
            LATERAL( -- this is the only change
                SELECT
                    books.name
                FROM
                    books
                WHERE
                    books.author_id = authors.id
                    AND books.sold > (
                        SELECT
                            avg(sold)
                        FROM
                            books
                        WHERE
                            books.author_id <> authors.id
                    )
            ) AS t
    ) AS good_selling_books
FROM
    authors
WHERE
    authors.id = 1
解决方案来自这篇博文,作者在博文中还注意到了DB2中的相同缺点:

但是DB2也没有将两个级别提升到S.c1。我想它可以,但是,唉,它没有


+这张海报混淆了他的范围。Subselect是独立的语句,其结果会暴露给外部select,而不是相反。@Eddy感谢您比我更明确地指出这一点。这没有意义。那么为什么第二个最里面的authors.id可以工作呢?顺便说一句,这个查询在PostgreSQL和SQL Server中运行得非常好。的确,第二个最内层的作者引用也有同样的问题。我的错。你说得对。然而,艾迪提出的范围界定点仍然是根本错误的。+1海报混淆了他的范围界定。Subselect是独立的语句,其结果会暴露给外部select,而不是相反。@Eddy感谢您比我更明确地指出这一点。这没有意义。那么为什么第二个最里面的authors.id可以工作呢?顺便说一句,这个查询在PostgreSQL和SQL Server中运行得非常好。的确,第二个最内层的作者引用也有同样的问题。我的错。你说得对。然而,Eddy提出的范围界定点仍然是根本错误的。事实上,我很惊讶这个查询在MySQL中不起作用。仅供参考,它在PostgreSQL和SQL Server中运行良好。无论如何,关于内部查询不能到达其他表的部分肯定是错误的。像SELECT a.key,SELECT count*FROM b,其中b.key=a.key作为count FROM a在任何数据库中都可以很好地工作。实际上,我很惊讶这个查询在MySQL中不起作用。仅供参考,它在PostgreSQL和SQL Server中运行良好。无论如何,关于内部查询不能到达其他表的部分肯定是错误的。查询,如SELECT a.key,SELECT count*FROM b,其中b.key=a.key as count FROM a在任何数据库中都可以正常工作。