通过 odbc 在 SQLITE 上的 power 查询中使用相关表中的计算列
Posted
技术标签:
【中文标题】通过 odbc 在 SQLITE 上的 power 查询中使用相关表中的计算列【英文标题】:Use computed columns in related table in power query on SQLITE via odbc 【发布时间】:2015-10-23 01:46:24 【问题描述】:在power query(exel 2016,PC附带的版本)中,是否可以引用相关表的计算列?
假设我有一个如下的 sqlite 数据库
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE products (
iddb INTEGER NOT NULL,
px FLOAT,
PRIMARY KEY (iddb)
);
INSERT INTO "products" VALUES(0,0.0);
INSERT INTO "products" VALUES(1,1.1);
INSERT INTO "products" VALUES(2,2.2);
INSERT INTO "products" VALUES(3,3.3);
INSERT INTO "products" VALUES(4,4.4);
CREATE TABLE sales (
iddb INTEGER NOT NULL,
quantity INTEGER,
product_iddb INTEGER,
PRIMARY KEY (iddb),
FOREIGN KEY(product_iddb) REFERENCES products (iddb)
);
INSERT INTO "sales" VALUES(0,0,0);
INSERT INTO "sales" VALUES(1,1,1);
INSERT INTO "sales" VALUES(2,2,2);
INSERT INTO "sales" VALUES(3,3,3);
INSERT INTO "sales" VALUES(4,4,4);
INSERT INTO "sales" VALUES(5,5,0);
INSERT INTO "sales" VALUES(6,6,1);
INSERT INTO "sales" VALUES(7,7,2);
INSERT INTO "sales" VALUES(8,8,3);
INSERT INTO "sales" VALUES(9,9,4);
COMMIT;
基本上我们有产品 (iddb, px) 和这些产品的销售额 (iddb, quantity, product_iddb)
我通过以下方式在电源查询中加载此数据:
A.使用 SQLITE3 驱动程序创建 ODBC 数据源:testDSN
B.在 excel 中:数据/新查询,提供此连接字符串 Provider=MSDASQL.1;Persist Security Info=False;DSN=testDSN;
现在在电源查询中,我向产品表添加了一个计算列,例如 px10 = px * 10
。
在sales 表中,我可以将product
表扩展为product.px
,但不能扩展为product.px10
。不应该是可行的吗? (在这个简化的例子中,我可以扩展第一个 product.px,然后在 sales 表中创建 px10 列,但是任何需要从 product 中获取 px10 的新表都需要我重复工作......)
任何意见表示赞赏。
【问题讨论】:
【参考方案1】:我会在销售查询中添加一个合并步骤,以将其连接到产品查询(其中将包括您的计算列)。然后我会展开返回的表以获取您的 px10 列。
这不是扩展表示产品 SQL 表的 Value 列,该表是使用 SQL 外键生成的。
您必须返回并将添加到产品查询的任何其他列添加到扩展列表中,但至少列定义仅在一个位置。
【讨论】:
【参考方案2】:在函数式编程中,您不会修改现有值,而只会创建新值。当您将新列添加到 product
时,它会创建一个新表,并且不会修改出现在相关表中的 product
表。在 product
上添加新列无法显示在 Odbc 的表中,除非您将该转换应用于所有相关表。
您可以做的是将“添加计算列”概括为一个函数,该函数采用表或记录并添加额外字段。然后将其应用于数据库中的每个表。
这是一个在 SQL Server 中针对 Northwind 的示例
let
Source = Sql.Database(".", "Northwind_Copy"),
AddAColumn = (data) => if data is table then Table.AddColumn(data, "UnitPrice10x", each [UnitPrice] * 10)
else if data is record then Record.AddField(data, "UnitPrice10x", data[UnitPrice] * 10)
else data,
TransformedSource = Table.TransformColumns(Source, "Data", (data) => if data is table then Table.TransformColumns(data, "Products", AddAColumn, null, MissingField.Ignore) else data),
OrderDetails = TransformedSource[Schema="dbo",Item="Order Details"][Data],
#"Expanded Products" = Table.ExpandRecordColumn(OrderDetails, "Products", "UnitPrice", "UnitPrice10x", "Products.UnitPrice", "Products.UnitPrice10x")
in
#"Expanded Products"
【讨论】:
感谢您拼凑代码并添加表格/记录的精妙之处。不过,必须为每个表复制函数感觉很笨拙;在 2010 版本的 power pivot 中,您只需使用 RELATED() 并能够访问额外的列,它更直观。以上是关于通过 odbc 在 SQLITE 上的 power 查询中使用相关表中的计算列的主要内容,如果未能解决你的问题,请参考以下文章
Excel-VBA 通过 ODBC 驱动程序到 SQLite3:主数据库 + 附加数据库