MS Access匹配结构表

时间:2017-01-20 12:25:39

标签: sql ms-access

我有一个有趣的问题要用表来克服。我已经从我们的完整零件数据库中存储了一组简化的数据(我们不能自由地进行攻击,并且不执行所需的查询)。我需要找到工程师创建完全克隆组件的位置,包括它们在空间中的位置(xyz位置和xyz旋转)和区域。我基本上需要列出它们以便在主系统中删除。该表显示了顶级程序集,它是第一级子程序。

Assembly_1
| - Part_1(0,0,0 0,0,0)
| - Part_2(0,0,0 0,0,0)
| - Part_3(0,0,0 0,0,0)

Assembly_2
| - Part_1(0,0,0 0,0,0)
| - Part_2(0,0,0 0,0,0)
| - Part_3(0,0,0 0,0,0)

Assembly_3
| - Part_1(500,0,0 0,0,0)
| - Part_2(500,0,0 0,0,0)
| - Part_3(500,0,0 0,0,0)

Assembly_4
| - Part_4(0,0,0 0,0,0)
| - Part_5(0,0,0 0,0,0)
| - Part_6(0,0,0 0,0,0)


存储在一个表中:

Parent ID  |  Child ID  | Assembly Level | Area | Position
Assembly_1 | Assembly_1 | 0              | 0001 | 0,0,0 0,0,0
Assembly_1 | Part_1     | 1              | 0001 | 0,0,0 0,0,0
Assembly_1 | Part_2     | 1              | 0001 | 0,0,0 0,0,0
Assembly_1 | Part_3     | 1              | 0001 | 0,0,0 0,0,0
Assembly_2 | Assembly_2 | 0              | 0001 | 0,0,0 0,0,0
Assembly_2 | Part_1     | 1              | 0001 | 0,0,0 0,0,0
Assembly_2 | Part_2     | 1              | 0001 | 0,0,0 0,0,0
Assembly_2 | Part_3     | 1              | 0001 | 0,0,0 0,0,0
Assembly_3 | Assembly_3 | 0              | 0001 | 0,0,0 0,0,0
Assembly_3 | Part_1     | 1              | 0001 | 500,0,0 0,0,0
Assembly_3 | Part_2     | 1              | 0001 | 500,0,0 0,0,0
Assembly_3 | Part_3     | 1              | 0001 | 500,0,0 0,0,0
Assembly_4 | Assembly_4 | 0              | 0002 | 0,0,0 0,0,0
Assembly_4 | Part_4     | 1              | 0002 | 0,0,0 0,0,0
Assembly_4 | Part_5     | 1              | 0002 | 0,0,0 0,0,0
Assembly_4 | Part_6     | 1              | 0002 | 0,0,0 0,0,0

在示例中,我希望Assemblies 1&虽然它使用相同的部件,但它的x,y,z位置不同,而不是装配4,因为它使用不同的部件并且位于不同的区域。

我想要提取的是:

 Assembly  | Cloned Assembly | Area
Assembly_1 |    Assembly_2   | 0001

我不介意你是否最终获得了第1组和第1组的额外线路。 2个交换方。即使这比手动搜索整个结构更加可口!

我怀疑此刻这可能最终成为一个VBA解决方案(主要是因为我理解VBA远远超过了解SQL!)因为我甚至无法在SQL中接近这一点,但这很费时间(我相信在完整数据集中搜索和比较的产品数量超过20000个,产品中有近400个区域),每个产品的重复次数大约为30 +。

我尝试过以下示例来提取重复项(实际上它已经很好地提取了0级组件被意外重复到产品中的位置),但这是一行与另一行匹配的地方,而不是一组几行与另一组相匹配。

非常感谢任何帮助/指导,甚至只是肯定使用VBA!

更新的SQL:

SELECT DISTINCT
   a1.GROUP,
   a1.SUB_GROUP,
   a1.ParentID AS Assembly,
   (SELECT DISTINCT AssemblyTable.NAME
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a1.ParentID) AS NAME,
   (SELECT DISTINCT AssemblyTable.OWNER
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a1.ParentID) AS OWNER,
   a1.Area,
   (SELECT DISTINCT AssemblyTable.ITEM_CREATION
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a1.ParentID) AS ITEM_CREATION,
   a2.ParentID AS CLONED_ASSEMBLY,
   (SELECT DISTINCT AssemblyTable.NAME
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a2.ParentID) AS CLONE_NAME,
   (SELECT DISTINCT AssemblyTable.OWNER
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a2.ParentID) AS CLONE_OWNER,
   (SELECT DISTINCT AssemblyTable.ITEM_CREATION
      FROM AssemblyTable
      WHERE AssemblyTable.ChildID=a2.ParentID) AS CLONE_CREATION
FROM (SELECT * FROM AssemblyTable ORDER BY AssemblyTable.ITEM_CREATION ASC) AS a1
   INNER JOIN (SELECT * FROM AssemblyTable ORDER BY AssemblyTable.ITEM_CREATION ASC) AS a2
      ON (a1.ParentID < a2.ParentID)
      AND (a1.Area = a2.Area)
      AND (a1.[Position] = a2.[Position])
      AND (a1.ChildID=a2.ChildID)
WHERE a1.ParentID<>a2.ParentID
ORDER BY a1.GROUP, a1.SUB_GROUP, a1.Area, a1.ParentID;

表现在是:

Parent ID  |  Child ID  |      Name       | OWNER  | Assembly Level | Area |   Position    | ITEM_CREATION
Assembly_1 | Assembly_1 | Assembly_1_Name | User_1 | 0              | 0001 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_1 | Part_1     | Part_1_Name     | User_1 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_1 | Part_2     | Part_2_Name     | User_1 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_1 | Part_3     | Part_3_Name     | User_1 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_2 | Assembly_2 | Assembly_2_Name | User_2 | 0              | 0001 | 0,0,0 0,0,0   |  01-01-2017  
Assembly_2 | Part_1     | Part_1_Name     | User_2 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2017  
Assembly_2 | Part_2     | Part_2_Name     | User_2 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2017  
Assembly_2 | Part_3     | Part_3_Name     | User_2 | 1              | 0001 | 0,0,0 0,0,0   |  01-01-2017  
Assembly_3 | Assembly_3 | Assembly_3_Name | User_3 | 0              | 0001 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_3 | Part_1     | Part_1_Name     | User_3 | 1              | 0001 | 500,0,0 0,0,0 |  01-01-2016  
Assembly_3 | Part_2     | Part_2_Name     | User_3 | 1              | 0001 | 500,0,0 0,0,0 |  01-01-2016  
Assembly_3 | Part_3     | Part_3_Name     | User_3 | 1              | 0001 | 500,0,0 0,0,0 |  01-01-2016  
Assembly_4 | Assembly_4 | Assembly_4_Name | User_4 | 0              | 0002 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_4 | Part_4     | Part_4_Name     | User_4 | 1              | 0002 | 0,0,0 0,0,0   |  01-01-2016  
Assembly_4 | Part_5     | Part_5_Name     | User_4 | 1              | 0002 | 0,0,0 0,0,0   | 01-01-2016  
Assembly_4 | Part_6     | Part_6_Name     | User_4 | 1              | 0002 | 0,0,0 0,0,0   | 01-01-2016

我偶尔会看到:

 Assembly  | Cloned Assembly | Area
Assembly_2 |    Assembly_1   | 0001

2 个答案:

答案 0 :(得分:0)

使用VBA肯定会更好,但是一些存储的查询可以帮助您加快比较过程。我将创建一个具有以下内容的查询:程序集ID,Count(ChildID),Min(子ID),Sum(整个程序集上的位置+旋转)。

这将很快消除大部分“不完全克隆”的可能性,只留下很少的部分来检查。

答案 1 :(得分:0)

考虑一个self join,您可以将同一个表连接到自身。在所需的匹配列上创建连接条件,然后筛选不同的 ParentID 。并且为了避免reverse duplicates使用大于/小于等于的特殊ON子句:

Self Join SQL Diagram

SELECT DISTINCT a1.ParentID AS Assembly, a2.ParentID AS ClonedAssembly, a1.Area
FROM AssemblyTable AS a1 
INNER JOIN AssemblyTable AS a2 
    ON (a1.ParentID < a2.ParentID) AND (a1.Area = a2.Area) 
    AND (a1.[Position] = a2.[Position]) AND (a1.ChildID = a2.ChildID)
WHERE a1.ParentID <> a2.ParentID;

-- Assembly    Cloned_Assembly  Area
-- Assembly_1       Assembly_2  0001