我有两个表,一个是项目目录,另一个包含这些项目的历史记录。
我想在与items表连接的时间段内返回最早和最新历史记录行的值,以便每个项目包含一行,其中包含这两个提到的值。
表结构如下:
items
-----
item_id, item_title
hist
-------
hist_id, hist_item_id (corresponds to items.item_id), hist_value, hist_time (stores Unix timestamp)
我创建了一个SQL小提琴,其中有一些示例数据可以帮助您,http://www.sqlfiddle.com/#!2/c78363/3
作为最终结果,我希望看到这样的行返回,使用我的小提琴中的示例数据将是1420291000和1420294000之间的时间段:
items.item_id items.item_title history_earliest history_latest
1 ABC 1 5
2 XYZ 1 9
目前我正在对项目运行查询以返回所有项目,然后在PHP中迭代这些结果,然后运行两个查询给我最早的值,然后另一个为最新值,所以我确信效率很高可以节省,但我不知道从哪里开始!
提前致谢
答案 0 :(得分:2)
您可以使用子查询。它不是唯一可行的解决方案,但它可能更容易理解(因此也更容易理解)。
从items
表中选择所有字段,并为每个项执行子查询以查找给定范围中最早的历史记录条目的值,另一个用于查找相同范围内的最新历史记录条目。
SELECT
items.*
,(SELECT hist_value
FROM hist
WHERE hist.hist_item_id = items.item_id
AND hist.hist_time BETWEEN 1420291000 AND 1420294000
ORDER BY hist_time ASC LIMIT 1
) history_earliest
,(SELECT hist_value
FROM hist
WHERE hist.hist_item_id = items.item_id
AND hist.hist_time BETWEEN 1420291000 AND 1420294000
ORDER BY hist_time DESC LIMIT 1
) history_latest
FROM items
答案 1 :(得分:2)
您可以使用GROUP_CONCAT获取时间范围内的所有值,当然您只需要第一个和最后一个值。您可以在代码中执行此操作,也可以使用SUBSTRING_INDEX执行此操作。
http://www.sqlfiddle.com/#!2/c78363/41
SELECT
items.item_id,
items.item_title,
SUBSTRING_INDEX(GROUP_CONCAT(hist.hist_value ORDER BY hist.hist_id ASC), ',', 1) AS earliest,
SUBSTRING_INDEX(GROUP_CONCAT(hist.hist_value ORDER BY hist.hist_id DESC), ',', 1) AS latest
FROM hist
INNER JOIN items ON hist.hist_item_id = items.item_id
WHERE hist.hist_time BETWEEN 1420291000 AND 1420294000
GROUP BY hist.hist_item_id
答案 2 :(得分:0)
<强>已更新强>
我知道已有答案,但请找另一种方式 - 也许某种程度上可以提供帮助( SQL Fiddle with UPDATED query and results ):
SELECT DISTINCT
items.*,
_hist_e_l.history_earliest,
_hist_e_l.history_latest
FROM
items
LEFT OUTER JOIN
(
SELECT
A.hist_item_id,
B.hist_value AS history_earliest,
C.hist_value AS history_latest
FROM
(SELECT hist.hist_item_id, MIN(hist.hist_time) AS history_earliest_time,
MAX(hist.hist_time) AS history_latest_time
FROM hist
WHERE
hist.hist_time >= 1420291000 AND hist.hist_time<= 1420294000
GROUP BY hist.hist_item_id
) AS A
INNER JOIN hist AS B
ON A.hist_item_id = B.hist_item_id
AND A.history_earliest_time = B.hist_time
INNER JOIN hist AS C
ON A.hist_item_id = C.hist_item_id
AND A.history_latest_time = C.hist_time
) AS _hist_e_l
ON items.item_id = _hist_e_l.hist_item_id
答案 3 :(得分:-1)
SELECT item_id, item_title, MIN(hist_TIME), MAX(hist_time)
FROM (items JOIN hist ON items.item_id = hist.hist_item_id)
GROUP BY item_id, item_title;
我不确定你到底想要完成什么。听起来您正在尝试创建两个数据集并将它们放在一个数据集中?那种无视数据集逻辑(SQL基于的东西)
您可以在上面的sql中放入子查询以获取x = y的计数。这可能是数据库上的性能代价