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 OperationIDorに変更すると実行されますが、列の下のテーブルWHERE PlantData.OperationID IN (SELECT OperationIDのすべての行にゼロが表示されます。CorpDataOperationID4Counter

私たちは近くにいると思いますが、葉巻はありません。ON StationName LIKE '%' || OperationName行を変更するとON StationName LIKE '%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

2 つ目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 は別の表で説明していますが、4 と 55 のように指定する 1 つまたは 2 つの ServiceID を検索したいと考えています。

注目すべき最後のデータ テーブル ( と呼びましょう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 も 1 つ含まれます 4) 1 つの CityID に複数の企業のプラントと同じ企業の複数の工場。4) 補足として、これはこのテーブルのほんの一部であり、特定の CorpID がこのテーブルに表示される回数をすべてカウントすると、その CorpID の PlantCount と同じになります (したがって、これは植物が見落とされていないことを確認するための何らかのチェック。)

質問

テーブルに 2 つの新しい列を追加したいと思いCorpDataます。どちらもカウントになります。1 つ目は、企業が ServiceID 4 を持つプラントの数をカウントし、2 つ目は、その企業が ServiceID 55 を持つプラントをいくつ持つかをカウントします。これを行うには、長いテーブルを調べて、各 PlantName からPlantData(テーブルから) OperationName を解析し、OperationName に対応する OperationID (テーブル内) を見つけて、その OperationID が ServiceID (から) と一緒にリストされているかどうかを確認する必要があります。表) 問題の(最初のケースでは 4 で、2 番目のケースでは 55 です。)OperationDataOperationDataServiceData

4 つのテーブルを .db ファイルに格納した sqlite3 を使用してこれを行うつもりですが、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 には 2 つの倉庫と 1 つの配送センターがあり、倉庫と配送センターは両方とも OperationID 4 を持っていますが、配送センターと工場のみが OperationID 55 を持ち、ACME Corp には工場、倉庫、配送センターがそれぞれ 1 つあり、工場はそうでないためです。 OperationID は 4 ですが、OperationID は 55 です。

その他の注意事項

これをよりトリッキーにする可能性があると私が思ういくつかのことを次に示します。

  1. PlantName にはいくつかの単語が含まれており、その部分がある場合とない場合がありUnit X -ます。OperationName は常に 1 語の長さだけではなく、CorpName は 2 語より多い (または少ない) 場合もあります。したがって、PlantName 内で OperationName を見つけるには、OperationName を含む可能性が高い部分だけを検索するために何らかの方法で断片に分割しようとするのではなく、おそらく全体を調べる必要があります。
  2. テーブルを下ってPlantData一致をカウントするとき、他の 2 つのテーブルをチェックして、行を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 に答える