我有两个不同的表来跟踪设备的位置。 “设备”表跟踪当前位置以及何时安装。如果设备先前位于不同的位置,则该信息保存在“locationHistory”表中。设备表中每个equip_id有一行。 locationHistory表中的每个equip_id可以有0个或更多条目。
equipment
equip_id
current_location
install_date_at_location
locationHistory
equip_id
location
install_date
pickup_date
我想要一个SQL查询,获取每个设备的第一个install_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 :(得分:1)
您需要将每个查看一个字段的查询联合起来,然后对其使用MIN。 或者您可以使用CASE和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
答案 1 :(得分:0)
嗯,关键的信息是设备中的install_at_location_date是否可以比我假设的位置历史中的历史信息少。如果那是不可能的,你可以这样做:
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
但是如果您不得不担心这两个表,则需要创建为您规范化表的视图,然后对视图应用查询:
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
答案 2 :(得分:0)
一种简单的方法是:
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表生成很多行,但是不清楚是否值得通过尝试将GROUP BY和MIN应用到UNION的后半部分来“优化”它(因为你是立即使用设备表中的信息重新进行分组。