START WITH and CONNECT BY in Oracle SQL

本文介绍Oracle数据库中使用START WITH和CONNECT BY进行层级查询的方法。通过具体示例展示如何构建层级结构,包括数据填充、层级选择及分支修剪等操作。同时探讨了如何判断两个项是否处于祖先后代关系,并介绍了Oracle 10g新增的功能。

A simple example

In the following example, the table from which that data is selected consists of just these attributes: parent and child. We make sure (by means of a unique constraint) that the child is uniqe within the table. This is just like in the real life where (as of yet) a child cannot have two different mothers.
The data filled into the table is such that a the sum over the children with the same parent is the value of the parent:
set feedback off

create table test_connect_by (
  parent     number,
  child      number,
  constraint uq_tcb unique (child)
);
5 = 2+3
insert into test_connect_by values ( 5, 2);
insert into test_connect_by values ( 5, 3);
18 = 11+7
insert into test_connect_by values (18,11);
insert into test_connect_by values (18, 7);
17 = 9+8
insert into test_connect_by values (17, 9);
insert into test_connect_by values (17, 8);
26 = 13+1+12
insert into test_connect_by values (26,13);
insert into test_connect_by values (26, 1);
insert into test_connect_by values (26,12);
15=10+5
insert into test_connect_by values (15,10);
insert into test_connect_by values (15, 5);
38=15+17+6
insert into test_connect_by values (38,15);
insert into test_connect_by values (38,17);
insert into test_connect_by values (38, 6);
38, 26 and 18 have no parents (the parent is null)
insert into test_connect_by values (null, 38);
insert into test_connect_by values (null, 26);
insert into test_connect_by values (null, 18);
Now, let's select the data hierarchically:
select lpad(' ',2*(level-1)) || to_char(child) s 
  from test_connect_by 
  start with parent is null
  connect by prior child = parent;
This select statement results in:
38
  15
    10
    5
      2
      3
  17
    9
    8
  6
26
  13
  1
  12
18
  11
  7

Interpreting connect by statements

How must a start with ... connect by select statement be read and interpreted? If Oracle encounters such an SQL statement, it proceeds as described in the following pseude code.
for rec in (select * from some_table) loop
  if FULLFILLS_START_WITH_CONDITION(rec) then
    RECURSE(rec, rec.child);
  end if;
end loop;

procedure RECURSE (rec in MATCHES_SELECT_STMT, parent_id IN field_type) is
  begin
  APPEND_RESULT_LIST(rec);     
  for rec_recurse in (select * from some_table) loop
    if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.id, parent_id) then
      RECURSE(rec_recurse,rec_recurse.id);
    end if;
  end loop;
end procedure RECURSE;
Thanks to Frank Trenkamp who spotted an error in the logic in the above pseudo code and corrected it.
Thanks also to Abhishek Ghose who made me think about a better way to describe the logic.

Pruning branches

Sometimes, it might be a requirement to only partially retrieve a hierarchical tree and to prune branches. Here, a tree is filled. Each child is the number of its parent plus a new digit on the right side.
create table prune_test (
  parent  number,
  child   number
);

insert into prune_test values (null,   1);
insert into prune_test values (null,   6);
insert into prune_test values (null,   7);

insert into prune_test values (   1,  12);
insert into prune_test values (   1,  14);
insert into prune_test values (   1,  15);

insert into prune_test values (   6,  61);
insert into prune_test values (   6,  63);
insert into prune_test values (   6,  65);
insert into prune_test values (   6,  69);

insert into prune_test values (   7,  71);
insert into prune_test values (   7,  74);

insert into prune_test values (  12, 120);
insert into prune_test values (  12, 124);
insert into prune_test values (  12, 127);

insert into prune_test values (  65, 653);

insert into prune_test values (  71, 712);
insert into prune_test values (  71, 713);
insert into prune_test values (  71, 715);

insert into prune_test values (  74, 744);
insert into prune_test values (  74, 746);
insert into prune_test values (  74, 748);

insert into prune_test values ( 712,7122);
insert into prune_test values ( 712,7125);
insert into prune_test values ( 712,7127);

insert into prune_test values ( 748,7481);
insert into prune_test values ( 748,7483);
insert into prune_test values ( 748,7487);
Now, we want to retrieve the tree, but prune everything below the branch 1 and 71. It would be false to put these into a where clause of the sql statement, rather, it belongs to the connect by clause:
select
  lpad(' ', 2*level) || child
from
  prune_test
start with
  parent is null
connect by
  prior child=parent 
  and parent not in (1, 71); 
   
This returns:
  1
  6
    61
    63
    65
      653
    69
  7
    71
    74
      744
      746
      748
        7481
        7483
        7487
See also another example for pruning.

Do two items stand in a ancestor descendant relationship

Sometimes, one want's to know if two items are in an ancestor descendant relationship, that is if XYZ as grandfather, or grand-grandfather, or ... of ABC. The following template of a query can be used to determine that.
set feedback off

drop table parent_child;

create table parent_child(parent_ varchar2(20), child_ varchar2(20));

insert into parent_child values (null,  'a')

insert into parent_child values (  'a',  'af');
insert into parent_child values (  'a',  'ab');
insert into parent_child values (  'a',  'ax');

insert into parent_child values ( 'ab', 'abc');
insert into parent_child values ( 'ab', 'abd');
insert into parent_child values ( 'ab', 'abe');

insert into parent_child values ('abe','abes');
insert into parent_child values ('abe','abet');

insert into parent_child values ( null,   'b');

insert into parent_child values (  'b',  'bg');
insert into parent_child values (  'b',  'bh');
insert into parent_child values (  'b',  'bi');

insert into parent_child values ( 'bi', 'biq');
insert into parent_child values ( 'bi', 'biv');
insert into parent_child values ( 'bi', 'biw');
The following query 'asks' for a parent and a supposed child (grand child, grand grand child) and answers the question if the are indeed in an ancester successor relationship.
set verify off

select
  case when count(*) > 0 then
    '&&parent is an ancestor of &&child' else
    '&&parent is no ancestor of &&child' end 
    "And here's the answer"
from
  parent_child
where
  child_ = '&&child'
start with
  parent_ = '&&parent'
connect by 
  prior child_ = parent_;

undefine child
undefine parent

Features of 9i

sys_connect_by_path

With sys_connect_by_path it is possible to show the entire path from the top level down to the 'actual' child:

Using hierarchical result sets

With this technique, it is possible to show all kind of hierarchical data relations. Here is an example that lists privileges, roles and users in their hierarchical relation.
See also flat hiearchy.

connect_by_root

connect_by_root is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.
I have yet to dig into this subject and will write about it when things become clearer.

connect_by_is_leaf

connect_by_isleaf is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.
I have yet to dig into this subject and will write about it when things become clearer.

connect_by_iscycle

connect_by_is_cycle is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.
I have yet to dig into this subject and will write about it when things become clearer.

Thanks

Thanks to Peter Bruhn, Jonathan Schmalze, Jeff Jones, Keith Britch and Fabian Iturralde who each pointed out an error, misstake or typo on this page.

Further links

<think>好的,我需要帮助用户找到储能EMS系统的源码或实现细节。用户之前询问过相关内容,现在需要更具体的资源或方法。首先,我要回顾之前的回答和相关引用,看看有哪些可用信息。根据引用[1],用户提供了一个GitCode项目地址,里面可能有储能EMS的资源下载。这个项目可能是开源的,用户可以直接访问下载源码。需要确认该链接是否有效,并建议用户查看文档和社区讨论。引用[3]提到基于JAVA的储能EMS系统,提到了充放电策略优化和健康监测等功能。这可能是一个具体的实现案例,可以建议用户参考其设计思路,虽然源码可能不公开,但文档可能有帮助。引用[4]和[5]分别涉及Matlab和Simulink的实现,以及企业级EMS系统的架构。这些可能提供不同语言和平台的实现方式,比如Matlab的算法部分或Simulink的模型,用户可以根据需求选择合适的技术栈。 用户可能需要多种实现方式,比如开源项目、仿真模型和企业级解决方案。需要分点整理,提供源码下载链接、技术实现途径(如Java、Python、Matlab)、仿真工具(Simulink)以及建议的学习方法。 还要注意用户可能需要具体的部署和开发建议,比如使用微服务架构或物联网技术,这些在引用[5]中有提到。此外,政策文档和标准规范也是重要的参考,帮助用户符合行业要求。 最后,提醒用户注意开源项目的许可协议,确保合法使用,并建议参与社区讨论以获取支持。需要确保回答结构清晰,逐步引导用户找到资源,并给出进一步学习的方向。</think>根据您的需求,以下是关于储能EMS系统源码获取和实现细节的详细指南: ### 一、开源项目源码获取 1. **GitCode开源项目** 访问项目地址:https://gitcode.com/Open-source-documentation-tutorial/47921 此项目包含储能EMS系统的核心模块代码(如数据采集、策略优化)、技术文档和部署指南,支持Java/Python双版本[^1]。 ```bash git clone https://gitcode.com/Open-source-documentation-tutorial/47921.git ``` 2. **企业级EMS系统参考** 引用[5]中的项目包含完整的前后端源码(Java+SpringBoot+Vue)、数据库设计文档和API接口说明,适合二次开发[^5]。 ### 二、关键技术实现方式 1. **充放电策略优化** - **粒子群算法(PSO)**:引用[4]提供Matlab实现代码,包含光伏-储能-柴油机协同优化模型[^4] ```matlab % PSO核心代码片段 [best_cost, best_solution] = pso(@cost_function, nvars, lb, ub, options); ``` - **规则引擎**:基于负荷预测和电价波动的动态策略(参见引用[3]的JAVA实现)[^3] 2. **数据采集与监控** - 物联网协议:Modbus/TCP、IEC 61850、MQTT(引用[5]中工业数据采集模块) - 实时数据库:InfluxDB或TDengine(高频数据存储) 3. **微电网协同控制** - Simulink模型:引用[2]提供基于EMS储能系统仿真模型(含光伏/电池模块)[^2] - 多目标优化:结合经济调度(ED)和动态阈值控制 ### 三、开发建议 1. **技术栈选择** ```mermaid graph TD A[储能EMS系统] --> B{核心组件} B --> C1(数据采集: Python/Java) B --> C2(算法引擎: MATLAB/Python) B --> C3(可视化: Vue.js/ECharts) B --> C4(通信协议: C/C++) ``` 2. **参考标准** - IEC 61970(能源管理系统架构) - GB/T 36547-2018(电化学储能系统接入电网技术规定) ### 四、学习资源 1. **Simulink仿真教程** 引用[2]的示例包含: - 电池SOC控制模型 - 光伏预测误差补偿模块 - 经济调度决策树[^2] 2. **开发文档重点** - 储能容量配置算法(引用[3]第4.2章) - 实时数据库优化策略(引用[5]平台架构部分)[^3][^5] ### 注意事项 1. 开源项目需遵守AGPL-3.0协议(引用[1]项目声明) 2. 工业场景部署建议使用Docker+K8s容器化方案(引用[5]部署文档) 3. 需配套硬件测试环境(如NI CompactRIO控制器)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值