4

答案

CL. 的答案就是诀窍!我最终使用了一个 Python 脚本(可以在下一节中查看,称为“更新:努力寻找答案”),一旦我正确设置了我的数据库,以便将 ID 列设置为整数键(或者,如果不可能,数字)并且名称列被设置为文本然后它起作用了!

更新:努力寻找答案

我尝试运行如下所示的 .py 文件:

import sqlite3
conn = sqlite3.connect('data.db')
c = conn.cursor()

c.executescript("""
UPDATE CorpData
SET OperationID4Counter =
      (SELECT COUNT(*)
       FROM PlantData JOIN OperationData
                      ON PlantName LIKE '%' || OperationName
       WHERE OperationID IN (SELECT OperationID
                             FROM ServiceData
                             WHERE ServiceID = 512)
         AND CorpID = CorpData.CorpID)
        """)

并得到这个错误:sqlite3.OperationalError: ambiguous column name: OperationID。我猜这是因为我们加入了 PlantData 和 OperationData,它们都有一个名为OperationID. 当我将该行代码更改为 read WHERE OperationData.OperationID IN (SELECT OperationIDorWHERE PlantData.OperationID IN (SELECT OperationID时,它会运行,但最终在列CorpData下的表的所有行中都为零OperationID4Counter

我想我们很接近了,但没有雪茄。我认为这条线有些地方不对,ON StationName LIKE '%' || OperationName因为当我将其更改为ON StationName LIKE '%house'(如果我理解正确的话,应该在“house”中得到所有结尾,其中包括 Warehouse)我仍然以 OperationID4Counter 的全零结束(甚至尽管它至少应该计算确实具有 OperationID4 的仓库。)

CL。要求提供一些 .dump 信息以查看该数据库中使用了哪些类型。我没有指定任何东西,所以它只是使用默认值。另请注意,各种表的列比我在示例中显示的列多(但还要注意,这些列与此问题无关,因为它们处理与手头问题无关的数据。)例如,一个PlantData 表的 .dump 如下所示:

INSERT INTO "PlantData" VALUES('60015145','0','0','50000000','10000','15','386
8','1000181','30003830','20000560','10000048','Anytown 334 - Unit 3 - Widgit Corp Logistics Center','-1.444E+12','-71312793600','-9.25528E+11','0.5','0.025','4
');

OperationData 中的 .dump 片段如下所示:

INSERT INTO "OperationData" VALUES('20','45','Manufacturing','','0','0','0','0',
'0','','','','','');

来自 CorpData 的 .dump 片段如下所示:

INSERT INTO "CorpData" VALUES(NULL,0,'1000158','Shapeset',' S',' N',' 500005','
XYZ Consortium',' 20','6','7','1','5','0');

背景和数据样本

我有 4 个表 - 我想从其中 3 个表中提取数据以在某些条件下增加一个计数器,然后将此计数器作为新列添加到第 4 个。我们称之为第 4 个表CorpData(我想添加更多数据)目前看起来像这样,通常有 10-50 行(注意我使用逗号来显示列分隔符):

CorpID, CorpName, Size, Type, PlantCount, OtherCounter1, OtherCounter2, OtherCounter3, OtherCounter4, OtherCounter5
100002, Widgit Corp, G, R, 25, 1, 5, 4, 3, 0
100004, ACME Corp, G, S, 15, 15, 4, 25, 28, 1

值得注意的部分是 CorpID(唯一键)和 PlantCount,它是该公司拥有多少工厂(即设施)的计数器。

这些附加数据源表中的第一个,我们称它OperationData有这样的数据,大约有 50 行:

OperationID, OperationName, Description
1, Warehouse, This facility stores items
2, Distribution Center, Items are brought her from Warehouses to be distributed
3, Factory, Goods are manufactured here

第二个,ServiceData大约有 700 行,看起来像这样:

OperationID, ServiceID
1, 4
1, 25
1, 33
1, 105
1, 19505
1, 32590
2, 4
2, 25
2, 55
2, 199
2, 19505
2, 335679
2, 529934
3, 2
3, 105
3, 55
3, 170
3, 48907

每个 ServiceID 都在另一个表中进行了解释,但我想搜索一个或两个 ServiceID,我将指定它们,例如 4 和 55。

最后一个需要注意的数据表,我们称之为PlantData,包含所有公司的所有工厂的详细信息,因此它有大约 5200 行,如下所示:

PlantID, CorpID, CityID, CountryID, PlantName
60000004, 100002, 74900, 34590, Somewhereville 123 - Widgit Corp Warehouse
60000007, 100002, 74878, 34590, Anytown 334 - Unit 3 - Widgit Corp Distribution Center
60000023, 100002, 56799, 23487, Quietville 532 - Unit 4 - Widgit Corp Warehouse
60000027, 100004, 74900, 34590, Somewhereville 544 - Unit 3 - ACME Corp Distribution Center
60000150, 100004, 56799, 23487, Quietville 312 - Unit 2 - ACME Corp Factory
60000155, 100004, 56799, 23487, Quietville 312 - Unit 4 - ACME Corp Warehouse

请注意以下几点: 1) 此表中的 CorpID 与我的起始表中的 CorpID 匹配 2) 给定 CorpID 的 CorpName 将始终出现在 PlantName 中 3) PlantName 还包含一个 OperationName 4) 一个 CityID 可以拥有多个公司的工厂以及同一公司的多个工厂。4)作为旁注,这只是该表的一小部分,如果您计算给定 CorpID 出现在该表中的所有时间,它将与该 CorpID 的 PlantCount 相同(因此这可以用作检查某种以确保没有遗漏任何植物。)

问题

我想在表中添加两个新列CorpData,它们都将是计数 - 第一个将是该公司拥有多少 ServiceID 4 的植物的计数,第二个是该公司拥有多少具有 ServiceID 55 的植物的计数。为此,我需要查看长PlantData表,从每个 PlantName 中解析出 OperationName(从OperationData表中),检查以找到 OperationName 对应的 OperationID(在OperationData表中),并查看该 OperationID 是否与 ServiceID 一起列出(来自表)有问题(第一种情况下为ServiceData4,第二种情况下为 55。)

我打算使用 sqlite3 来执行此操作,并将我的 4 个表存储在一个 .db 文件中,但如果你能提出一个可靠的理由,为什么我应该在 sqlite3 上使用该选项,我可能会对其他选项持开放态度。

目标

鉴于此处的示例,我的最终目标是使CorpData表格如下所示:

CorpID, CorpName, Size, Type, PlantCount, OtherCounter1, OtherCounter2, OtherCounter3, OtherCounter4, OtherCounter5, OperationID4Counter, OperationID55Counter
100002, Widgit Corp, G, R, 25, 1, 5, 4, 3, 0, 3, 1
100004, ACME Corp, G, S, 15, 15, 4, 25, 28, 1, 2, 2

这是因为 Widgit Corp 有两个仓库和一个配送中心,仓库和配送中心都有 OperationID 4,但只有配送中心和工厂的 OperationID 为 55,ACME Corp 各有 1 个工厂、仓库和配送中心,而工厂没有有 OperationID 4 但他们确实有 OperationID 55。

其他注意事项

以下是一些我认为可能会使事情变得更棘手的事情:

  1. PlantName 包含几个单词,它可能有也可能没有Unit X -。OperationName 并不总是只有一个词长,CorpName 也可以多于(或少于)两个词。因此,在 PlantName 中查找 OperationName 可能必须查看整个内容,而不是尝试以某种方式将其拆分为几块以仅搜索可能包含 OperationName 的部分。
  2. 当我们沿着PlantData表格向下工作并计算匹配项时,我们必须继续检查另外两个表格,看看是否PlantData应该计算其中的一行。我担心如果这段代码没有正确构建,它最终可能会很慢。
  3. 至少对我来说很难把所有这些都包起来,所以可能很容易引用错误的表,或者错过从 OperationName 到相应 OperationID 之类的搜索步骤。
4

1 回答 1

1
UPDATE CorpData
SET OperationID4Counter =
      (SELECT COUNT(*)
       FROM PlantData JOIN OperationData
                      ON PlantName LIKE '%' || OperationName
       WHERE OperationData.OperationID IN (SELECT OperationID
                                           FROM ServiceData
                                           WHERE ServiceID = 4)
         AND CorpID = CorpData.CorpID)
于 2012-11-10T15:44:48.923 回答