oracle子查询问题与Rownum和Order in where子句中的订单无效的外部表格

发布于 2025-02-12 04:11:23 字数 1235 浏览 1 评论 0原文

我正在尝试找到一种解决SQL查询的方法。我想做一个子查询以首先选择产品ID的启用文章。实际上,我正在研究查询的一部分。我只需要一篇文章作为一个产品,或者如果没有启用文章,则最终禁用了最后一个禁用。问题在于,我被要求不使用加入而不使用请求加入。这是传统应用。

这是一个工作示例:

from T_PRODUIT pro, T_PRODUIT_PLATEFORME_EXTENDED pre, T_ARTICLE art, T_TAUX_TVA tva
where pro.id_produit = 1330442 
and art.id_article in (select id_article from T_ARTICLE ta where ta.id_produit = pro.id_produit and ta.id_fournisseur = pre.id_fournisseur_article) 
and pro.ID_PRODUIT = pre.ID_PRODUIT
and pre.ID_PRODUIT = art.ID_PRODUIT(+)
and pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR(+)
and tva.CODE = pro.ID_TVA

我想要的是:

  from T_PRODUIT pro, T_PRODUIT_PLATEFORME_EXTENDED pre, T_ARTICLE art, T_TAUX_TVA tva
    where pro.id_produit = 1330442 
    and art.id_article in (select * from (select id_article from T_ARTICLE ta where ta.id_produit     = pro.id_produit and ta.id_fournisseur = pre.id_fournisseur_article order by ta.actif DESC) where rownum < 2)
    and pro.ID_PRODUIT = pre.ID_PRODUIT
    and pre.ID_PRODUIT = art.ID_PRODUIT(+)
    and pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR(+)
    and tva.CODE = pro.ID_TVA

第二个示例的问题是,在这种情况下,有两个嵌套级别,Pro和Pre是无效的标识符。有人知道我如何绕过这个问题? 该数据库有时包含引起复杂SQL的奇怪行。 谢谢。

I'm trying to find a way to resolve an sql query. I want to do a subquery to select enable articles for a product id in first. In fact i'm working on a part of a query. I would want just one article for a product the last enable or else the last disable if no enable articles. The problem is that i was asked to not use join with request without join at first. It's legacy app.

Here is a working example :

from T_PRODUIT pro, T_PRODUIT_PLATEFORME_EXTENDED pre, T_ARTICLE art, T_TAUX_TVA tva
where pro.id_produit = 1330442 
and art.id_article in (select id_article from T_ARTICLE ta where ta.id_produit = pro.id_produit and ta.id_fournisseur = pre.id_fournisseur_article) 
and pro.ID_PRODUIT = pre.ID_PRODUIT
and pre.ID_PRODUIT = art.ID_PRODUIT(+)
and pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR(+)
and tva.CODE = pro.ID_TVA

and what i would want :

  from T_PRODUIT pro, T_PRODUIT_PLATEFORME_EXTENDED pre, T_ARTICLE art, T_TAUX_TVA tva
    where pro.id_produit = 1330442 
    and art.id_article in (select * from (select id_article from T_ARTICLE ta where ta.id_produit     = pro.id_produit and ta.id_fournisseur = pre.id_fournisseur_article order by ta.actif DESC) where rownum < 2)
    and pro.ID_PRODUIT = pre.ID_PRODUIT
    and pre.ID_PRODUIT = art.ID_PRODUIT(+)
    and pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR(+)
    and tva.CODE = pro.ID_TVA

The problem with the second example is that there are two nesting level and pro and pre are invalid identifiers in this case. Someone know how i can bypass this problem ?
The database sometimes contains strange rows causing complex sql.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺ぐ爱和你が 2025-02-19 04:11:24

在Oracle 12中,您可以使用fet fetter第一行语法:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN T_ARTICLE art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442 
AND    art.id_article in ( select id_article
                           from    T_ARTICLE ta
                           where   ta.id_produit     = pro.id_produit
                           and     ta.id_fournisseur = pre.id_fournisseur_article 
                           order by ta.actif DESC
                           FETCH FIRST ROW ONLY
                         )

注意:您可能需要在过滤条件中移动该on on 加入条款,使其是外部联接条件的一部分;否则,您将有效地将外部Join转换为内在

在早期版本中,您可以使用:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN T_ARTICLE art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442 
AND    art.id_article in ( select ta.id_article
                           from    (
                             SELECT id_produit,
                                    id_fournisseur,
                                    id_article
                             FROM   T_ARTICLE
                             order by actif DESC
                           ) ta
                           where   ta.id_produit     = pro.id_produit
                           and     ta.id_fournisseur = pre.id_fournisseur_article
                           and     ROWNUM < 2
                         )

注意:再次,您可能需要移动它进入联接条件。

,您可能想要的是:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN (
         SELECT ta.*,
                ROW_NUMBER() OVER (
                  PARTITION BY ID_PRODUIT, ID_FOURNISSEUR
                  ORDER     BY actif DESC
                ) AS rn
         FROM   T_ARTICLE ta
       ) art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR
          AND art.rn = 1)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442

或者,使用遗产加入:

from   T_PRODUIT pro,
       T_PRODUIT_PLATEFORME_EXTENDED pre,
       (
         SELECT ta.*,
                ROW_NUMBER() OVER (
                  PARTITION BY ID_PRODUIT, ID_FOURNISSEUR
                  ORDER     BY actif DESC
                ) AS rn
         FROM   T_ARTICLE ta
       ) art,
       T_TAUX_TVA tva
WHERE  pro.id_produit             = 1330442
AND    pro.ID_PRODUIT             = pre.ID_PRODUIT
AND    tva.CODE                   = pro.ID_TVA
AND    pre.ID_PRODUIT             = art.ID_PRODUIT (+)
AND    pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR (+)
AND    1                          = art.rn (+)

From Oracle 12, you can use the FETCH FIRST ROW ONLY syntax:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN T_ARTICLE art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442 
AND    art.id_article in ( select id_article
                           from    T_ARTICLE ta
                           where   ta.id_produit     = pro.id_produit
                           and     ta.id_fournisseur = pre.id_fournisseur_article 
                           order by ta.actif DESC
                           FETCH FIRST ROW ONLY
                         )

Note: You may want to move that IN filter condition to the ON clause of the join so that it is part of the outer join condition; otherwise you are effectively converting the OUTER JOIN to an INNER JOIN.

In earlier versions you can use:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN T_ARTICLE art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442 
AND    art.id_article in ( select ta.id_article
                           from    (
                             SELECT id_produit,
                                    id_fournisseur,
                                    id_article
                             FROM   T_ARTICLE
                             order by actif DESC
                           ) ta
                           where   ta.id_produit     = pro.id_produit
                           and     ta.id_fournisseur = pre.id_fournisseur_article
                           and     ROWNUM < 2
                         )

Note: again, you may want to move it into the join condition.

However, what you probably want is:

from   T_PRODUIT pro
       INNER JOIN T_PRODUIT_PLATEFORME_EXTENDED pre
       ON (pro.ID_PRODUIT = pre.ID_PRODUIT)
       LEFT OUTER JOIN (
         SELECT ta.*,
                ROW_NUMBER() OVER (
                  PARTITION BY ID_PRODUIT, ID_FOURNISSEUR
                  ORDER     BY actif DESC
                ) AS rn
         FROM   T_ARTICLE ta
       ) art
       ON (   pre.ID_PRODUIT = art.ID_PRODUIT
          AND pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR
          AND art.rn = 1)
       INNER JOIN T_TAUX_TVA tva
       ON (tva.CODE = pro.ID_TVA)
WHERE  pro.id_produit = 1330442

Or, using the legacy joins:

from   T_PRODUIT pro,
       T_PRODUIT_PLATEFORME_EXTENDED pre,
       (
         SELECT ta.*,
                ROW_NUMBER() OVER (
                  PARTITION BY ID_PRODUIT, ID_FOURNISSEUR
                  ORDER     BY actif DESC
                ) AS rn
         FROM   T_ARTICLE ta
       ) art,
       T_TAUX_TVA tva
WHERE  pro.id_produit             = 1330442
AND    pro.ID_PRODUIT             = pre.ID_PRODUIT
AND    tva.CODE                   = pro.ID_TVA
AND    pre.ID_PRODUIT             = art.ID_PRODUIT (+)
AND    pre.ID_FOURNISSEUR_ARTICLE = art.ID_FOURNISSEUR (+)
AND    1                          = art.rn (+)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文