0

簡単に言えば、これらのテーブルがあります。

Planning: 
  Date | Machine | Product | PlanningParts

OKParts: 
  Date | Machine | Product | OKParts

Scrap: 
  Date | Machine | Product | ScrapParts

Trials: 
  Date | Machine | Product | TrialParts

Breakdowns: 
  Date | Machine | Product | Minutes

これらのテーブルには、同じ [日付 | 日付] に対して複数のレコードを含めることができます。マシン | Product]、それらは一意の列ではありません。この出力を得るのに最適な SQL コード (SQLite または SQL Server) は何ですか?

Output:
  Date | Machine | Product | Planning | OKParts | ScrapParts | TrialParts | Minutes

編集: 出力では、[Date,Machine,Product] ごとに 1 行が必要で、残りの列は SUM でなければなりません (私は英語を話せません、申し訳ありません)。

Eidted: 例: (表を短くするために「Trials」という表は入れません)

Planning:
     Date    | Machine | Product | PlanningParts
     1/6/12  |  Blower | A001    | 100
     2/6/12  |  Blower | A002    | 100
     2/6/12  | Assembly| B001    | 50

OKParts:
     Date   | Machine | Product  | OKParts
     1/6/12 | Blower  | A001     | 50
     1/6/12 | Blower  | A001     | 20
     1/6/12 | Blower  | A002     | 100

Scrap:
     Date   | Machine | Product  | ScrapParts | Reason
     1/6/12 | Blower  | A001     | 5          | Low Weight
     1/6/12 | Blower  | A001     | 3          | High Weight
     2/6/12 | Assembly| B001     | 4          | Bad Cut

Breakdowns
     Date   | Machine | Product  | Minutes    | Reason
     1/6/12 | Blower  | A001     | 100        | Manteinance
     1/6/12 | Blower  | A001     | 20         | Manteinance
     2/6/12 | Assembly| B001     | 100        | Quality approval


   OUTPUT:
         Date   | Machine | Product  | Planning | OKParts | ScrapParts | Breakdowns
         1/6/12 | Blower  | A001     | 100      | 70      | 8          | 120
         1/6/12 | Blower  | A002     | 100      | 100     | 0          | 0
         2/6/12 | Assembly| B001     | 50       | 0       | 4          | 100
4

2 に答える 2

3

すべてのテーブルを 1 つに結合する CTE を作成し、SUM 集計関数を使用して、日付、マシン、製品の各グループの列を合計します。このようなビット (テストされていません):

WITH AllParts AS (
SELECT Date, Machine, Product, PlanningParts, NULL AS OKParts, NULL AS ScrapParts, NULL AS TrialParts, NULL AS Breakdowns
FROM Planning
UNION ALL
SELECT Date, Machine, Product,NULL AS PlanningParts, OKParts, NULL AS ScrapParts, NULL AS TrialParts, NULL AS Breakdowns
FROM OKParts
UNION ALL
SELECT Date, Machine, Product,NULL AS PlanningParts, NULL AS OKParts, ScrapParts, NULL AS TrialParts, NULL AS Breakdowns
FROM Scrap
UNION ALL
SELECT Date, Machine, Product,NULL AS PlanningParts, NULL AS OKParts, NULL AS ScrapParts, TrialParts, NULL AS Breakdowns
FROM Trials
UNION ALL
SELECT Date, Machine, Product,NULL AS PlanningParts, NULL AS OKParts, NULL AS ScrapParts, TrialParts, Breakdowns
FROM BreakDowns
)
SELECT
Date, Machine, Product, SUM(OKParts) AS OKParts, SUM(ScrapParts) AS ScrapParts, SUM(TrialParts) AS TrialParts, SUM(BreakDowns) AS Breakdowns
FROM AllParts
GROUP BY Date, Machine, Product
于 2012-07-05T22:38:29.910 に答える
1

UNIONの後にSUMを実行するかどうか、および最初にSUMを実行するこのクエリを確認したいと思います。

WITH Vals AS (
   SELECT Date, Machine, Product, 'PlanningParts' Which, Sum(PlanningParts) Value FROM Planning GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'OKParts', Sum(OKParts) FROM OKParts GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'ScrapParts', Sum(ScrapParts) FROM Scrap GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'TrialParts', Sum(TrialParts) FROM Trials GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'Minutes', Sum(Minutes) FROM Breakdowns GROUP BY Date, Machine, Product
)
SELECT *
FROM Vals
PIVOT (Max(Value) FOR Which IN (PlanningParts, OKParts, ScrapParts, TrialParts, Minutes)) P;

ええ、それは苦痛ですが、それはあなたが与えられたデータベース設計から得られるものです。これらの5つのテーブルを1つのテーブルにリファクタリングし、代わりにトリガーを持つこれらのテーブルをビューで置き換えることが実行可能である可能性があります。

注:PIVOTは、SQLServer2005以降用です。しかし、PIVOTも必要ありません。

WITH Vals AS (
   SELECT Date, Machine, Product, 'PlanningParts' Which, Sum(PlanningParts) Value FROM Planning GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'OKParts', Sum(OKParts) FROM OKParts GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'ScrapParts', Sum(ScrapParts) FROM Scrap GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'TrialParts', Sum(TrialParts) FROM Trials GROUP BY Date, Machine, Product
   UNION ALL SELECT Date, Machine, Product, 'Minutes', Sum(Minutes) FROM Breakdowns GROUP BY Date, Machine, Product
)
SELECT
   Date, Machine, Product,
   Sum(CASE Which WHEN 'PlanningParts' THEN Value END) PlanningParts,
   Sum(CASE Which WHEN 'OKParts' THEN Value END) OKParts,
   Sum(CASE Which WHEN 'ScrapParts' THEN Value END) ScrapParts,
   Sum(CASE Which WHEN 'TrialParts' THEN Value END) TrialParts,
   Sum(CASE Which WHEN 'Minutes' THEN Value END) Minutes
FROM Vals;

テキストWhich値を整数に切り替えると、おそらく速度が向上します。

テーブルにある日付、マシン、製品の値の明確なリストを持つテーブルに関する私のコメント/質問に関して、このクエリはそのようなリストを提供します。これはうまく機能しませんが、それはあなたにアイデアを与えるはずです。

WITH DistinctKeys AS ( --wishing we had this as a real table
   SELECT Date, Machine, Product FROM Planning
   UNION SELECT Date, Machine, Product FROM OKParts
   UNION SELECT Date, Machine, Product FROM Scrap
   UNION SELECT Date, Machine, Product FROM Trials
   UNION SELECT Date, Machine, Product FROM Breakdown
) -- because then we could do this:
SELECT
   K.Date, K.Machine, K.Part,
   (SELECT Sum(PlanningParts) FROM Planning X ON EXISTS (SELECT K.* INTERSECT SELECT X.Date, X.Machine, X.Product) PlanningParts
   (SELECT Sum(OKParts) FROM OKParts X ON EXISTS (SELECT K.* INTERSECT SELECT X.Date, X.Machine, X.Product) OKParts
   (SELECT Sum(ScrapParts) FROM Scrap X ON EXISTS (SELECT K.* INTERSECT SELECT X.Date, X.Machine, X.Product) Scrap
   (SELECT Sum(TrialParts) FROM Trials X ON EXISTS (SELECT K.* INTERSECT SELECT X.Date, X.Machine, X.Product) TrialParts
   (SELECT Sum(Minutes) FROM Breakdown X ON EXISTS (SELECT K.* INTERSECT SELECT X.Date, X.Machine, X.Product) Minutes
FROM
   DistinctKeys K;

しかし率直に言って、JOINは、以前に私の回答と@jaypeagiの回答で示したUNIONと同じようには機能しません。

もう1つ、クエリのパフォーマンスがどうなるかを想定しないでください。専門家でさえ、実行計画をチェックし、実際のIOおよびCPU統計を収集して、この情報を決定します。NULLがパフォーマンスを低下させることについてのあなたの心配は、おそらく完全に根拠がありません。

[Date、Machine、Product]のテーブルに適切なインデックスがある場合は、UNIONメソッドからかなり良好なパフォーマンスが得られる可能性があります。

于 2012-07-05T23:07:47.343 に答える