加入具有不同优先级的许多(> 20)数据源

时间:2011-08-30 19:15:23

标签: sql database ms-access join

我已经在这个问题上工作了很长一段时间,似乎无法找到一个可接受的解决方案。问题是我有许多不同的数据源(至少20个),我已经归结为拥有我想要的相同的六或七列数据。我的目标是创建一个“Universe”,其中包含每个数据源上列出的所有项目。大多数数据列在多个来源上,有些仅在一个或两个来源上列出。我需要跟踪哪些来源有什么项目。最终,我的目标是在一列中包含“Universe”中每个项目的表格,然后是一系列标记其中所标识的每个源的列(即,如果Source 12包含当前内容,则源12的列将获得“x”项目)。此外,还有一些列包含有关项目的信息(其官方名称)。所有项目都有一个唯一的编号,但它们有不同的名称,因此在最后的表格中我生成我需要列出具有最高优先级的源名称。因此,如果项目位于源1上,请使用源1中列出的名称;如果没有,但它在源2上,使用为源2中的项目列出的名称;等等。

我正在使用Microsoft Access进行此操作,直到最近才能够使用唯一编号加入我的所有源表,并执行大型嵌套Iif语句以按源顺序获取名称'优先级,例如

Iif(Not Null(Source1.ItemName), Source1.ItemName, 
  Iif(NotNull(Source2.ItemName), Source2.ItemName, 
    Iif(...... ))))

然而,我现在遇到了一个问题,因为我一直在添加更多来源。访问限制了Iif语句的嵌套方式。所以,我试了几个不同的解决方案。我尝试使用VBA按优先级顺序在每个源表上运行select查询,直到找到与当前唯一编号匹配的记录,并返回在找到它的最高优先级源中列出的项目名称。问题是这个函数需要为每个唯一的数字运行几次,因为除了项目名称之外还有一些属性。这会导致非常慢查询。

另一种我尝试过的方法效果很好(但后来因为我将解释的其他原因而失败)是自我加入。我有一个查询(query1)来自所有源的唯一编号,项目名称和其他属性的并集,以及为源级别添加列。然后另一个查询(query2)有一个子查询,该子查询按唯一编号分组,并选择最小源级别,内部连接到query1以获取查询1中列出的最高排名源的记录的其余部分。但问题是,在我的最终查询中,我需要获取该信息,并添加标记,指出该项目的源代码,这需要大约20个左连接。另外,有些源有其他人没有的数据,所以我不能只将这些列添加到query1 union。所以,虽然我解决了多个嵌套的Iif问题,但我仍然遇到需要太多连接的问题。

如何获得包含所有项目属性和源列的最终表?

4 个答案:

答案 0 :(得分:1)

为了将列压缩在一起,您可以使用SQL标准函数COALESCE

Access不支持COALESCE,但如果有NZ功能。可悲的是,后者只需要1个参数,而不是像COALESCE那样的无限数量。

如果你想要一列中的所有内容,你可以像这样做一个大的UNION

 SELECT a AS OneColumnToRuleThemAll FROM (
  SELECT col1 as a FROM a
UNION
  SELECT col2 as a FROM b
UNION 
  SELECT ....) S

这会将所有内容放在一列中。

答案 1 :(得分:0)

2步骤怎么样?在第一步中,使用union将所有记录组合到一个包含所有公共列的表中,包括唯一ID,优先级,然后是名称和其他列。这不需要是插入查询,因此您不需要实际的表。

这不会将每个源作为是/否列提供给您,但每个唯一标识符的每个源都有一行,这可能同样好。

如果要为每一行显示最高优先级名称,可以使用Name列的子查询进行选择。

答案 2 :(得分:0)

我昨晚实际上已经解决了一些问题。如果其他人有类似的问题,这就是我做的:

1)我的一个联合查询(query1就是我上面所说的)仍然有唯一的数字,项目名称,公共属性,源名称和源标志(我们用它来指示它是否是新的宇宙与否)。

2)创建了一个新的交叉表查询(我称之为query1_crosstab),其中行标题为唯一编号,列标题为源名称,值为(交叉表属性)作为源标志。另一种方法是将值设置为count(item_name),将1放在源具有相关项的位置,或者将Iif(count(item_name)= 1,“x”,null)设置为把x改为(我们更喜欢做什么)

3)创建了一个新的分组查询,它与上面的query2相同,即按唯一编号分组并选择最小源编号并重新加入联合查询1以从排名最高的源中获取项目名称。

4)最后一个新查询基于唯一编号加入2)和3),以便在查询中列出所有常见属性以及每个项目在每个源中的存在信息。

5)最后,我可以将此查询连接到任何源表(仅2个),这些表具有不是所有表共有的额外属性。或者在第一步(联合)中,可以添加列以包含所有属性,而源中不存在的列只能具有空值。

我希望这有助于某人!

答案 3 :(得分:0)

我会这样做:

SELECT UniqueNumber, Name, 1 as TablePriority FROM Table1
  UNION ALL
SELECT UniqueNumber, Name, 2 as TablePriority FROM Table2
  UNION ALL
SELECT UniqueNumber, Name, 3 as TablePriority FROM Table3
  UNION ALL
SELECT UniqueNumber, Name, 4 as TablePriority FROM Table4
  UNION ALL
SELECT UniqueNumber, Name, 5 as TablePriority FROM Table5
  etc
ORDER BY TablePriority DESC