2011-01-23 9 views
1

私は2つの異なるテーブルを使って機器の位置を追跡しています。 「機器」テーブルは、現在の場所とそこにインストールされた時刻を追跡します。機器が以前は別の場所にあった場合、その情報は「locationHistory」テーブルに保持されます。機器テーブルには、equip_idごとに1つの行があります。 locationHistoryテーブルには、equip_idごとに0つ以上のエントリがあります。私はeqipmentの各部分のためのFIRST INSTALL_DATEの日付を取得するSQLクエリをしたい2つの異なるフィールドの最小値を得るためのSQL

equipment 
    equip_id 
    current_location 
    install_date_at_location 

locationHistory 
    equip_id 
    location 
    install_date 
    pickup_date 

...

例:

equipment 
========= 
equip_id | current_location | install_date_at_location 
    123 location1   1/23/2011 

locationHistory 
=============== 
equip_id | location | install_date | pickup_date 
    123 location2 1/1/2011  1/5/2011 
    123 location3 1/7/2011  1/20/2011 

が返す必要があります:123, 1/1/2011

思考?

+0

どのデータベースですか? –

+2

あなたは自分自身をより簡単にすることができ、データベースを正規化して*すべて* location/installデータを 'locationHistory'テーブルに持たせることができます。 –

+0

@oli Charlesworth:履歴のレコードを別のテーブルに移動することは、テーブルの分割方法と同様にパフォーマンスを向上させます。 –

答えて

1

それぞれが1つのフィールドを見ているクエリを結合し、それに対してMINを使用するとします。 それとも、まあ同じ効果

select e.equip_id, MIN(CASE WHEN h.install_date < e.install_date_at_location 
    THEN h.install_date 
    ELSE e.install_date_at_location 
END) as first_install_date 
from equipment e 
left join locationHistory h on h.equip_id = e.equip_id 
group by e.equip_id 
0

用CASEとMINを使用することができますが、情報の重要な部分は、機器内install_at_location_dateが今まで私がlocationHistoryの歴史的な情報であると仮定し何よりも少なくすることができるかどうかです。

SELECT * FROM locationHistory L INNER JOIN 
    (SELECT equip_id, MIN(install_date) AS firstDate FROM locationHistory) 
    AS firstInstalls F 
    ON L.equip_id = F.equip_id AND L.install_date = F.firstDate 

をしかし、あなたは、両方のテーブルを心配する必要があれば、あなたはあなたのためのテーブルを正規化ビューを作成し、ビューに対してクエリを適用する必要があります:それができないなら、あなたは行うことができます

SELECT U.Equip_ID, MIN(U.Install_Date) 
    FROM (SELECT E.Equip_ID, E.Install_Date_At_Location AS Install_Date 
      FROM Equipment AS E 
     UNION 
     SELECT L.Equip_ID, L.Install_Date 
      FROM LocationHistory AS L 
     ) AS U 
GROUP BY U.Equip_ID 

これはLocationHistoryテーブルからの行の多くを生成することができますが、それは価値が適用しようとすることで、それを「最適化」であることは明らかではない:

CREATE VIEW normalLocations (equip_id, location, install_date) AS 
    SELECT equip_id, location, install_date_at_location FROM equipment 
    UNION ALL 
    SELECT equip_id, location, install_date FROM equipment; 

SELECT * FROM normalLocations L INNER JOIN 
    (SELECT equip_id, MIN(install_date) AS firstDate FROM normalLocations) 
     AS firstInstalls F 
    ON L.equip_id = F.equip_id AND L.install_date = F.firstDate 
0

それを行うための簡単な方法ですグループBYとMINをUNIONの後半に追加します(これは、機器テーブルの情報から結果をグループ分けし直すためです)。

関連する問題