Firebird SQL 查询查找数据中的循环

发布于 2024-10-05 02:49:36 字数 1260 浏览 3 评论 0原文

我在编写 SQL 查询来查找 Firebird 表中的数据“循环”时遇到问题。

解释这种情况非常困难,所以我宁愿举一个例子:

Table: Explosion    

Stockcode   | IngredientStockcode
----------------------------------
001         | 010 
001         | 011
001         | 012

010         | 011
010         | 013
010         | 014    

012         | 013
012         | 015
012         | 001 <-- This causes a loop in my data. Stockcode 001 has an 
                      ingredient of 012 and stockcode 012 has 001 as 
                      an ingredient.

013         | 014
013         | 015
013         | 001 <-- This also causes a loop in my data. 013 is part of (an
                      ingredient of) 010. 010 is also an ingredient of 001. 001
                      cannot then also be an ingredient of 013.

我需要编写一个查询来识别数据中的这些“循环”。任何帮助将不胜感激。

这应该是一个带有连接的复杂查询。我已经尝试过下面这样的事情,我想我可能走在正确的道路上。

select * FROM explosion x1
WHERE EXISTS ( SELECT 1 FROM Explosion x2
               where exists ( SELECT 1 FROM Explosion x3 where
                              x3.ingredientStockcode = x1.Stockcode
                              AND x1.RDB$DB_KEY < x3.RDB$DB_KEY)
and x1.ingredientStockcode = x2.Stockcode
AND x1.RDB$DB_KEY < x2.RDB$DB_KEY)

I am having trouble writing an SQL query to find a data "loop" in my Firebird table.

Its very difficult to explain the situation so I will rather give an example:

Table: Explosion    

Stockcode   | IngredientStockcode
----------------------------------
001         | 010 
001         | 011
001         | 012

010         | 011
010         | 013
010         | 014    

012         | 013
012         | 015
012         | 001 <-- This causes a loop in my data. Stockcode 001 has an 
                      ingredient of 012 and stockcode 012 has 001 as 
                      an ingredient.

013         | 014
013         | 015
013         | 001 <-- This also causes a loop in my data. 013 is part of (an
                      ingredient of) 010. 010 is also an ingredient of 001. 001
                      cannot then also be an ingredient of 013.

I need to write a query to identify these "loops" in the data. Any help would be appreciated.

This should be a complex query with joins. I have already tried something like this below and I think I might be on the right track..

select * FROM explosion x1
WHERE EXISTS ( SELECT 1 FROM Explosion x2
               where exists ( SELECT 1 FROM Explosion x3 where
                              x3.ingredientStockcode = x1.Stockcode
                              AND x1.RDB$DB_KEY < x3.RDB$DB_KEY)
and x1.ingredientStockcode = x2.Stockcode
AND x1.RDB$DB_KEY < x2.RDB$DB_KEY)

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

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

发布评论

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

评论(2

假装不在乎 2024-10-12 02:49:36

这里有一个典型的图/树问题。

恐怕一次查询无法解决您的问题。您需要一个循环来遍历每棵树。

但是你还有另一个问题,你不能轻易选择根节点。因此,您要么需要标记根节点,要么自下而上遍历树(因此从没有其他成分的基本成分开始)。

对于此类数据,第二种选择更自然,因为某些东西总是可用于创建更复杂的东西。

您可以在 google 上搜索 SQL 中树的算法。

成功

You have a typical graph/tree problem here.

I'm afraid that one single query won't solve your issue. You'll need a loop to traverse each tree.

But you have another problem, you can't easily select the root nodes. So you will either need to mark the root nodes or traverse your trees bottom up (so beginning with the basic ingredients that have no further ingredients).

The second option is more natural for this kind of data because something is always usable to create something more complex.

You can search google for algoritmes for trees in SQL.

Success

分開簡單 2024-10-12 02:49:36

我不确定 firebird SQL 语法,但这个通用 SQL 查询应该可以帮助您:

select *  
from Explosion e1
inner join Explosion e2 
        on e1.Stockcode = e2.IngredientStockcode
       and e1.IngredientStockcode = e2.Stockcode

编辑

进行了快速检查,文档似乎表明上述内容可行。不过,为了以防万一,另一种语法是:

select *  
  from Explosion e1, Explosion e2
 where e1.Stockcode = e2.IngredientStockcode
   and e1.IngredientStockcode = e2.Stockcode

I'm not sure about the firebird SQL syntax, but this generic SQL Query shold help you:

select *  
from Explosion e1
inner join Explosion e2 
        on e1.Stockcode = e2.IngredientStockcode
       and e1.IngredientStockcode = e2.Stockcode

EDIT

Had a quick check, and the documentation seems to suggest the above will work. However, just in case, an alternative syntax is:

select *  
  from Explosion e1, Explosion e2
 where e1.Stockcode = e2.IngredientStockcode
   and e1.IngredientStockcode = e2.Stockcode
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文