Sql 表示实体网络之间关系的流程数据
事实如下:Sql 表示实体网络之间关系的流程数据,sql,Sql,事实如下: 有很多公司 每个公司都可以有很多业务 有很多地址 你不知道哪些公司(或公司名称)拥有哪些业务 但是,您知道每家企业的地址,并且您知道一家企业可能在多个地址进行交易 在地址之间建立关系: 如果一家企业的地址与另一家企业的地址相同,那么就这个问题而言,我们会说它们属于同一家公司 当一家公司同时使用两个地址时,两个地址之间就形成了链接 因此,一个地址“A”可能链接到许多其他地址 请注意: 6a。地址“A”链接到的地址也可能链接到一个或多个地址 6b。“A”链接到的其中一个地址可能通过第三个
如何使用纯SQL实现这一点,无论是使用递归连接还是其他技术(不是使用存储过程)?这是一个粗糙而蹩脚的解决方案(可能效率不高),但它得到了正确的结果。它通过维护到公司的两个映射(其中公司包含一个企业名称列表)来实现。第一个将业务地址映射到公司,第二个将业务名称映射到公司。如果在任一映射中都找不到公司,则会创建一个新公司:-
package test;
import org.junit.Assert;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
public class Companies {
public static List<Company> listCompanies(List<Business> businesses) {
List<Company> companies = new ArrayList<>();
Map<String, Company> companyByAddress = new HashMap<>(); // map allows many addresses to map to same company
Map<String, Company> companyByBusiness = new HashMap<>(); // map allows many businesses to map to same company
for (Business business : businesses) {
Company company = companyByAddress.get(business.address);
if (company == null)
company = companyByBusiness.get(business.name);
if (company != null) {
company.addAddress(business.name);
} else {
company = new Company();
company.addAddress(business.name);
companies.add(company);
}
companyByBusiness.put(business.name, company);
companyByAddress.put(business.address, company);
}
return companies;
}
@Test
public void testOne() {
List<Business> businesses = new ArrayList<>();
businesses.add(new Business("A", "1"));
businesses.add(new Business("A", "2"));
businesses.add(new Business("B", "1"));
businesses.add(new Business("C", "3"));
businesses.add(new Business("D", "4"));
businesses.add(new Business("E", "4"));
businesses.add(new Business("F", "4"));
businesses.add(new Business("G", "4"));
businesses.add(new Business("W", "2"));
businesses.add(new Business("W", "5"));
businesses.add(new Business("X", "5"));
businesses.add(new Business("X", "6"));
List<Company> companies = listCompanies(businesses);
Assert.assertEquals("A, B, W, X", companies.get(0));
Assert.assertEquals("C", companies.get(1));
Assert.assertEquals("D, E, F, G", companies.get(2));
}
static class Business {
private final String name;
private final String address;
Business(String business, String address) {
this.name = business;
this.address = address;
}
}
static class Company {
private final Set<String> addresses; // Being a "Set", each address will occur only once
Company() {
this.addresses = new LinkedHashSet<>(); // A "LinkedHashSet" preserves insertion order
}
void addAddress(String address) {
addresses.add(address);
}
@Override
public String toString() {
return addresses.stream().collect(Collectors.joining(", "));
}
}
}
封装测试;
导入org.junit.Assert;
导入org.junit.Test;
导入java.util.*;
导入java.util.stream.collector;
上市公司{
公开静态上市公司(上市业务){
上市公司=新ArrayList();
Map companyByAddress=new HashMap();//Map允许多个地址映射到同一个公司
Map companybusiness=new HashMap();//Map允许多个业务映射到同一个公司
用于(业务:业务){
Company Company=companyByAddress.get(business.address);
如果(公司==null)
company=companybusiness.get(business.name);
如果(公司!=null){
公司地址(业务名称);
}否则{
公司=新公司();
公司地址(业务名称);
公司。添加(公司);
}
companybusiness.put(business.name,company);
companyByAddress.put(business.address,company);
}
返回公司;
}
@试验
公共void testOne(){
列表业务=新建ArrayList();
增加(新业务(“A”、“1”));
增加(新业务(“A”、“2”));
增加(新业务(“B”、“1”);
增加(新业务(“C”、“3”));
增加(新业务(“D”、“4”);
增加(新业务(“E”、“4”));
增加(新业务(“F”、“4”));
增加(新业务(“G”、“4”));
增加(新业务(“W”、“2”));
增加(新业务(“W”、“5”));
增加(新业务(“X”、“5”));
增加(新业务(“X”、“6”));
上市公司=上市公司(企业);
Assert.assertEquals(“A,B,W,X”,companys.get(0));
Assert.assertEquals(“C”,companys.get(1));
Assert.assertEquals(“D,E,F,G”,companys.get(2));
}
静态类业务{
私有最终字符串名;
私有最终字符串地址;
业务(字符串业务,字符串地址){
this.name=业务;
this.address=地址;
}
}
静态类公司{
私有最终集地址;//作为一个“集”,每个地址只出现一次
公司(){
this.addresses=new LinkedHashSet();//一个“LinkedHashSet”保留插入顺序
}
无效地址(字符串地址){
地址。添加(地址);
}
@凌驾
公共字符串toString(){
返回地址.stream().collect(collector.joining(“,”);
}
}
}
这是SQL Server的答案
引述答覆:
澄清:
- 一个企业可以有多个地址
- 企业集团中的任何企业(即公司)与集团中的任何其他企业共享一个地址
- 一个业务组可以拥有多个业务
- 每个业务仅与一个业务组关联(第二点的推论)
我们可以用第一个(最小的)名称来表示每个业务组 按字母顺序排列)组中的业务。我们将其称为键 业务。在我们确定了每个业务的关键业务之后, 我们可以根据关键业务进行分组并获得结果 为了获得关键业务:
WITH Pairs AS (
SELECT Businesses.Business AS Business2, MIN(Businesses_1.Business) AS Business1
FROM Businesses
INNER JOIN Businesses AS Businesses_1 ON Businesses.Address = Businesses_1.Address
WHERE Businesses.Business > Businesses_1.Business
GROUP BY Businesses.Business
),
KeyBusinesses AS (
SELECT Business2 AS Business, Business1 AS KeyBusiness
FROM Pairs
UNION ALL
SELECT Pairs.Business2, KeyBusinesses.KeyBusiness
FROM Pairs
INNER JOIN KeyBusinesses ON Pairs.Business1 = KeyBusinesses.Business
)
SELECT Businesses.*, ISNULL(KeyBusinesses.KeyBusiness, Businesses.Business) AS KeyBusiness
FROM Businesses
LEFT JOIN KeyBusinesses ON Businesses.Business = KeyBusinesses.Business
- 根据任何共享地址生成两个业务位于同一组中的业务对列表。此列表应排除 以下内容(原因见下一点):
,当我们有A->B
B->A
A->A
对的左侧应该是唯一的:每个业务应该出现在对的左侧不超过一次,如果有的话<
package test;
import org.junit.Assert;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
public class Companies {
public static List<Company> listCompanies(List<Business> businesses) {
List<Company> companies = new ArrayList<>();
Map<String, Company> companyByAddress = new HashMap<>(); // map allows many addresses to map to same company
Map<String, Company> companyByBusiness = new HashMap<>(); // map allows many businesses to map to same company
for (Business business : businesses) {
Company company = companyByAddress.get(business.address);
if (company == null)
company = companyByBusiness.get(business.name);
if (company != null) {
company.addAddress(business.name);
} else {
company = new Company();
company.addAddress(business.name);
companies.add(company);
}
companyByBusiness.put(business.name, company);
companyByAddress.put(business.address, company);
}
return companies;
}
@Test
public void testOne() {
List<Business> businesses = new ArrayList<>();
businesses.add(new Business("A", "1"));
businesses.add(new Business("A", "2"));
businesses.add(new Business("B", "1"));
businesses.add(new Business("C", "3"));
businesses.add(new Business("D", "4"));
businesses.add(new Business("E", "4"));
businesses.add(new Business("F", "4"));
businesses.add(new Business("G", "4"));
businesses.add(new Business("W", "2"));
businesses.add(new Business("W", "5"));
businesses.add(new Business("X", "5"));
businesses.add(new Business("X", "6"));
List<Company> companies = listCompanies(businesses);
Assert.assertEquals("A, B, W, X", companies.get(0));
Assert.assertEquals("C", companies.get(1));
Assert.assertEquals("D, E, F, G", companies.get(2));
}
static class Business {
private final String name;
private final String address;
Business(String business, String address) {
this.name = business;
this.address = address;
}
}
static class Company {
private final Set<String> addresses; // Being a "Set", each address will occur only once
Company() {
this.addresses = new LinkedHashSet<>(); // A "LinkedHashSet" preserves insertion order
}
void addAddress(String address) {
addresses.add(address);
}
@Override
public String toString() {
return addresses.stream().collect(Collectors.joining(", "));
}
}
}
WITH Pairs AS (
SELECT Businesses.Business AS Business2, MIN(Businesses_1.Business) AS Business1
FROM Businesses
INNER JOIN Businesses AS Businesses_1 ON Businesses.Address = Businesses_1.Address
WHERE Businesses.Business > Businesses_1.Business
GROUP BY Businesses.Business
),
KeyBusinesses AS (
SELECT Business2 AS Business, Business1 AS KeyBusiness
FROM Pairs
UNION ALL
SELECT Pairs.Business2, KeyBusinesses.KeyBusiness
FROM Pairs
INNER JOIN KeyBusinesses ON Pairs.Business1 = KeyBusinesses.Business
)
SELECT Businesses.*, ISNULL(KeyBusinesses.KeyBusiness, Businesses.Business) AS KeyBusiness
FROM Businesses
LEFT JOIN KeyBusinesses ON Businesses.Business = KeyBusinesses.Business