Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 让所有没有孩子的父母,或者如果有孩子,让最新的孩子_Sql - Fatal编程技术网

Sql 让所有没有孩子的父母,或者如果有孩子,让最新的孩子

Sql 让所有没有孩子的父母,或者如果有孩子,让最新的孩子,sql,Sql,我有下面的订单。orderId是主键,parentOrderId是表示此订单是否具有父订单的列 例:1,2,3,4没有父订单。5,6,7,8有上级订单 +--------------------+----------------------+ | order_id | parent_order_id | +--------------------+----------------------+ | 1 |

我有下面的订单。orderId是主键,parentOrderId是表示此订单是否具有父订单的列

例:1,2,3,4没有父订单。5,6,7,8有上级订单

+--------------------+----------------------+
|          order_id   | parent_order_id     |
+--------------------+----------------------+
|                  1 |                  null|
|                  2 |                  null|
|                  3 |                  null|
|                  4 |                  null|
|                  5 |                    1 |
|                  6 |                    2 |
|                  7 |                    3 |
|                  8 |                    3 |
+--------------------+----------------------+



I need to query all Parents with no children or if there are children only get the latest child. 
The result I need is : 4,5,6,8
   4 because it has no children and should be returned.
   5 because it is the only child of 1.
   6 because that is the only child of 2.
   8 because 3 has 2 children(7,8) and I need to return latest child. Pick max of orderId's.
我尝试的是:

我要找的是:

上面的查询返回4,5,6,8。问题是我将此查询输入IN子句,oracle对IN子句的限制为1000。我试图看看是否有更好的方法来解决这个问题使用连接。 更新: 联接将帮助我检索order表中的所有列,而不仅仅是id,为了简单起见,我只包括了两列,表中还有更多列。现在,我获取id的第一个,并在另一个查询中的子句中提供它们,以获取与这些id匹配的所有列

我也在寻找不是特定于供应商的sql


谢谢您的帮助。

这里有一种解决此问题的方法,使用connect by查询,它实际上是一种连接形式,针对分层数据进行了优化,就像您的查询一样。WITH子句不是解决方案的一部分,它只是用来模拟您的输入。使用实际的表名和列名

请注意,在我询问的结果中,我还得到了order_id=5的行。在我的评论中,您回答了其他问题,但没有回答这个问题

这显示了如何在一次传递中获得所需的所有列

with
  orders_table (order_id, parent_order_id) as (
    select 1, null from dual union all
    select 2, null from dual union all
    select 3, null from dual union all
    select 4, null from dual union all
    select 5, 1    from dual union all
    select 6, 2    from dual union all
    select 7, 3    from dual union all
    select 8, 3    from dual
  )
select order_id, parent_order_id
from   (
         select     o.*
              ,     max(order_id)
                        over (partition by connect_by_root order_id) as max_id
         from       orders_table o
         where      connect_by_isleaf = 1
         start with parent_order_id is null
         connect by parent_order_id = prior order_id
       )
where  order_id = max_id
;

ORDER_ID  PARENT_ORDER_ID
--------  ---------------
       5                1
       6                2
       8                3
       4    

OP在对我的另一个答案的评论中解释说,他需要一个尽可能使用标准SQL特性的查询。这排除了connect by查询,也排除了像nvl这样简单的工具

下面的查询得到相同的结果。它不太一般,但它可以解决OP的问题,即只有父节点和子节点,而没有第三代节点

与我的另一个答案一样,它的编写是为了能够选择原始表或某些相关子集中的所有列。这最好用解析函数来完成,正如我在另一个答案中所做的那样

with
  orders_table (order_id, parent_order_id) as (
    select 1, null from dual union all
    select 2, null from dual union all
    select 3, null from dual union all
    select 4, null from dual union all
    select 5, 1    from dual union all
    select 6, 2    from dual union all
    select 7, 3    from dual union all
    select 8, 3    from dual
  )
select order_id, parent_order_id
from   (
         select o.* 
              , max(order_id) over 
                     (partition by coalesce(parent_order_id, order_id)) as max_id
         from   orders_table o
       )
where order_id = max_id
;

1000限值适用于a,即固定值列表;如果您直接使用子查询,即。。。在选择。。。联合所有。。。减从orders中,子查询可以返回的行数没有限制。也许有更好的方法可以做到这一点,但你可能是从一个错误的理解开始的。@alex poole感谢你的回答。按照应用程序的设计方式,我必须执行两个单独的查询,一个是获取所有有效id,另一个是使用in子句中的列表获取这些id的所有详细信息。我考虑的另一种选择是一次批处理1000个id,然后在第一组1000个id或第二组1000个id中进行……以此类推。不确定这样做是否正确。为什么5不能达到预期效果?它是我唯一的孩子。然后——分别地——如果父母有多个孩子,你如何定义最新的孩子?最新的,以什么标准衡量?简单地按照标签的字母顺序或数字顺序排列,所以8>7或字符串'8'>7'表示8是最新的?这很奇怪;如果有多个子项,是否有一个额外的列用于排序子项?另外:您的表是否只有父代和子代,或者链是否可以有三代或更多代?此外,您对1000多个结果的讨论以及使用联接等都没有意义。如果您执行现在正在执行的操作,保存结果,然后将它们硬编码到IN子句中,那么根据哪个查询生成1000多个结果,这种情况会发生什么变化?无论什么查询生成结果,无论它使用UNIONALL、join还是分层查询,都可能是最好的选择,您不会遇到完全相同的问题吗?解决方案是修改应用程序,以便在单个查询中完成所需的所有操作。否则,必须创建一个临时表,将第一个查询的结果保存到该表中,然后从临时表中选择in条件。但与正确答案相比,这是一个相当蹩脚的解决方案,正确答案是在一个查询中获取所有内容。谢谢@mathguy。看起来没有连接方式的解决方案是不可能的?我问的原因是我需要将上述查询转换为查询dsl jpa查询,我可能无法这样做,因为这是特定于oracle的。完全可以使用join语法重写此查询。当我有时间的时候,我会提出一种方法。然而,这些限制应该永远是你问题的一部分;现在,在你的原始帖子中没有关于它的任何内容,标签只是sql和oracle-没有迹象表明oracle解决方案不适合你。同意,我的错。但我会记住这一点。我的印象是,我应该能够翻译任何sql查询,但忽略了一个事实,即在本例中,查询可以是特定于供应商的Oracle。非常感谢您的回复,谢谢。这个使用group by的修改版本同样有效:select*from orders\U table,其中order\U id位于select maxorder\U id中
通过合并父级订单id、订单id从订单表组@rohith-好的,但是在查询中,您从表中读取了两次数据。引入分析函数的具体目的是避免这种需要——多次读取数据。
with
  orders_table (order_id, parent_order_id) as (
    select 1, null from dual union all
    select 2, null from dual union all
    select 3, null from dual union all
    select 4, null from dual union all
    select 5, 1    from dual union all
    select 6, 2    from dual union all
    select 7, 3    from dual union all
    select 8, 3    from dual
  )
select order_id, parent_order_id
from   (
         select o.* 
              , max(order_id) over 
                     (partition by coalesce(parent_order_id, order_id)) as max_id
         from   orders_table o
       )
where order_id = max_id
;