2016-11-18 47 views
0

我搜索了一下,发现了很多类似的东西,但并不完全符合我的要求。MS Access(通过VB.NET) - 将链接的属性表转换为输出中的列

我有什么本质上是一堆带有属性和值的链接表。

xxBio table 

xxBio_ID xxBio_LINK 
1   100 
2   101 



xx table 

xxBio_LINK xxAttr_LINK 
100   1000 
101   2000 



xxAttr table 

xxAttr_LINK xxAttrCat_1_LINK xxAttrCat_2_LINK 
1000  null    550 
2000  650     null 



xxAttrCat_1 table 

xxAttrCat_1_LINK xxAttrCat_1_Description  xxAttrCat_1_Value 
650     wumpus      20 


xxAttrCat_2 table 

xxAttrCat_2_LINK xxAttrCat_2_Description  xxAttrCat_2_Value 
550     frith      30 

输出要求是:

xxBio_ID frith wumpus 
1   30  null 
2   null 20 

我可以很容易地看到如何得到的结果与像attribute_name1,attribute_value1,attribute_name2,attribute_value2等栏目设置。

SELECT xxBio.ID, xxAttrCat_1.xxAttrCat_1_Description, xxAttrCat_1.xxAttrCat_1_Value, xxAttrCat_2.xxAttrCat_2_Description, xxAttrCat_2.xxAttrCat_2_Value 

FROM ((

(xx INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK) 

INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK) 

LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK) 
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK 

但这不是我们所需要的。我们需要属性名称作为列名。

我们如何实现这一目标?

更新质疑: 原来,我们误解了要求,所以我们不得不采取了不同的路线,并没有得到尝试的答案。我很感激帮助。

回答

0

将SQL放入字符串中并从VBA执行。 (?动态SQL)

sql = "SELECT xxBio.ID, " & xxAttrCat_1.xxAttrCat_1_Description & ", " & ... 
+0

刚想过这个。上面这个可以用来创建你的表,但是随后的传递将会被要求把这些记录写到这个表中,就像你的例子一样。 – geeFlo

0

考虑使用IIF()条件语句:

SELECT xxBio.ID,  
     IIF(xxAttrCat_1.xxAttrCat_1_Description = 'wumpus', 
      xxAttrCat_1.xxAttrCat_1_Value, NULL) As [wumpus], 
     IIF(xxAttrCat_2.xxAttrCat_2_Description = 'frith', 
      xxAttrCat_2.xxAttrCat_2_Value, NULL) As [frith]  
FROM (((xx 
INNER JOIN xxBio ON xx.xxBio_LINK = xxBio.xxBio_LINK) 
INNER JOIN xxAttr ON xx.xxAttr_LINK = xxAttr.xxAttr_LINK) 
LEFT JOIN xxAttrCat_1 ON xxAttr.xxAttrCat_1_LINK = xxAttrCat_1.xxAttrCat_1_LINK) 
LEFT JOIN xxAttrCat_2 ON xxAttr.xxAttrCat_2_LINK = xxAttrCat_2.xxAttrCat_2_LINK 

如果每个ID都可以沿着相同的描述多个值,你需要总结或平均所有相应的值,然后将查询转换为条件聚合(称为透视)。为了简洁和组织,下面还使用表别名a,b,c1,c2

SELECT b.ID,  
     SUM(IIF(c1.xxAttrCat_1_Description='wumpus', c1.xxAttrCat_1_Value, NULL)) As [wumpus], 
     SUM(IIF(c2.xxAttrCat_2_Description='frith', c2.xxAttrCat_2_Value, NULL)) As [frith]  
FROM (((xx 
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK) 
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK) 
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK) 
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK 
GROUP BY b.ID 

如果这样的描述可以多次使用MS Access SQL的crosstab查询。但是由于您有两个类别,请在每个类别上运行一个交叉表并将它们保存为已存储的查询或视图。然后,联合起来:

--CATEGORY 1 
TRANSFORM SUM(c1.xxAttrCat_1_Value) AS SumOfValue 
SELECT b.ID,      
FROM ((xx 
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK) 
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK) 
LEFT JOIN xxAttrCat_1 c1 ON a.xxAttrCat_1_LINK = c1.xxAttrCat_1_LINK 
GROUP BY b.ID 
PIVOT c1.xxAttrCat_1_Description; 

--CATEGORY 2 
TRANSFORM SUM(c2.xxAttrCat_2_Value) AS SumOfValue 
SELECT b.ID,      
FROM ((xx 
INNER JOIN xxBio b ON xx.xxBio_LINK = b.xxBio_LINK) 
INNER JOIN xxAttr a ON xx.xxAttr_LINK = a.xxAttr_LINK) 
LEFT JOIN xxAttrCat_2 c2 ON a.xxAttrCat_2_LINK = c2.xxAttrCat_2_LINK 
GROUP BY b.ID 
PIVOT c2.xxAttrCat_2_Description; 

--CROSSTAB QUERIES JOIN 
SELECT c1.*, c2.* 
FROM Categ1CrossTabQ c1 
INNER JOIN Categ1CrossTabQ c2 
ON c1.ID = c2.ID; 

请注意:以上双破折号注释在Access查询中不允许的,只有一个语句被允许在保存的查询。每个表/查询的访问限制为255列,因此,除非使用IN子句,否则大于255的透视值将错误出现。最后,你不能使用交叉表作为子查询。而交叉表完全是MS Access命令,并未在其他DBMS中使用。