生成SQL JOIN语句

时间:2011-04-18 06:39:56

标签: java sql algorithm join primary-key

背景

以下数据是一般问题的具体示例(按列名排序):

Primary Key: as_comp.companynamecurrent.companyid
Primary Key: as_comp.companylocation.companyid
Primary Key: as_comp.companylocation.locationid
Primary Key: as_hr.personemploymentcurrent.locationid
Primary Key: as_hr.personnamecurrent.personid
Primary Key: as_hr.personemploymentcurrent.personid
Primary Key: as_hr.personaddresscurrent.personid
Primary Key: as_hr.personemploymentcurrent.positionid

实际上,主键及其关系的数量是动态的(在运行时未知)。生成唯一主键列表的代码类似于以下内容:

// Remove duplicate columns by using a set.
//
Set<String> joins = new HashSet<String>( bundles.size() );

for( Bundle b : bundles.keySet() ) {
  joins.add( b.getColumn() );
}

// Match the primary keys in the bundles.
//
for( Bundle b : bundles.keySet() ) {
  if( joins.contains( b.getColumn() ) ) {
    System.out.println( "Primary Key: " + b.toString() );
  }
}

每个Bundle(如&#34;资源包&#34;国际化项)实例包含架构,表(或视图),列名和用于唯一标识数据库列的其他信息便于翻译。每个Bundle都可以通过isJoin()方法回答它是否是主键约束:

boolean bundle.isJoin()

问题

根据上一节中的数据,创建一组JOIN子句,如下所示:

join as_comp_companylocation as_comp_companylocation on (as_hr_personemploymentcurrent.locationid == as_comp_companylocation.locationid)
join as_hr_personnamecurrent as_hr_personnamecurrent on (as_hr_personemploymentcurrent.personid == as_hr_personnamecurrent.personid)
join as_hr_personaddresscurrent as_hr_personaddresscurrent on (as_hr_personemploymentcurrent.personid == as_hr_personaddresscurrent.personid)
join as_comp_companynamecurrent as_comp_companynamecurrent on (as_comp_companylocation.companyid == as_comp_companynamecurrent.companyid)

请注意,positionid可以删除,因为不需要加入。

更新

左侧比较条件操作数是主键,其对应的表(或视图)名称列出两次(或更多)。这会产生:

  • companylocation
  • personemploymentcurrent

问题

如何使用给定的数据集创建JOIN语句?

非常感谢。

3 个答案:

答案 0 :(得分:1)

这不一定非常难。

您基本上拥有的是一个表格图表,其边缘描述了表格的连接方式。

然后,当您有要加入的表列表时,您将启动并开始搜索图表。在您浏览图表时,请跟踪连接条件和访问过的节点。

我会详尽地搜索图表,这可能会导致几个路径链接所有表格。只需选择最短的路径。

最后,使用表名作为键并缓存结果,然后您只需要搜索每个唯一表集的图表。这里没有真正的魔力,我不认为,在此之前你必须要有很多表可能会花费任何真正明显的时间。它还为您提供了能够选择两个未直接连接的表的好处,该路径将找到进行连接所需的任何中间表。

答案 1 :(得分:0)

如果它像你描述的那样是静态的,我将静态地准备查询,并根据所选的集群查找它们。即没有涉及算法。

太简单了?吻:)

答案 2 :(得分:0)

算法结果相当深入。基本上:

  1. 获取列映射列表。
  2. 如果列是主键,请根据其唯一可识别名称将其放入地图中。
  3. 删除重复的主键。
  4. 对主键进行排序。
  5. 创建新地图以计算(统计)主键出现的次数。
  6. 创建“重复列表”以存储多次出现的主键列。
  7. 对已排序的主键进行迭代。
  8. 将多次出现的每个主键添加到“重复列表”。
  9. 迭代重复的主键。
  10. 遍历所有连接列。
  11. 如果列等于其中一个重复项,请将其添加到比较器列列表中。
  12. 创建一个新字符串以保存SQL“join”子句文本。
  13. 遍历比较器列(主操作数)和排序列(辅助操作数)。
  14. 如果主操作数和辅助操作数具有相同的列名,但来自不同的表,则根据操作数构建“join”子句。
  15. 将join子句存储在列表中。
  16. 欢迎改进。