Php 最近日期(今天、昨天或之前)的Mysql查询内部联接

Php 最近日期(今天、昨天或之前)的Mysql查询内部联接,php,mysql,Php,Mysql,我试图从内部联接的表中提取最新的定价数据。价格全天更新,但不必在午夜更新 当一天结束时更新价格数据时,下面的查询非常有效。但是,如果今天的数据是空白的,我如何获取昨天的数据呢 我从一个列中编制索引,该列的格式如下date\u itemnumber=>2015-05-22\u 12341234 SELECT h.*, collection.*, history.price FROM collection INNER JOIN h ON collection.itemid=h.id INNER JO

我试图从内部联接的表中提取最新的定价数据。价格全天更新,但不必在午夜更新

当一天结束时更新价格数据时,下面的查询非常有效。但是,如果今天的数据是空白的,我如何获取昨天的数据呢

我从一个列中编制索引,该列的格式如下
date\u itemnumber
=>
2015-05-22\u 12341234

SELECT h.*, collection.*, history.price
FROM collection
INNER JOIN h ON collection.itemid=h.id
INNER JOIN history ON collection.itemid=history.itemid 
AND concat('2015-05-23_',collection.itemid)=history.date_itemid
WHERE h.description LIKE '%Awesome%'
生产查询时间:.046秒

为了清楚起见,我希望它检查该项目的最新记录。不管是今天、昨天还是之前

下面的查询为我提供了所需的结果,但对于我的生产数据集,返回结果需要3分钟以上。随着我的数据集越来越大,它将花费更长的时间。所以这不是最有效的方法

SELECT h.*, collection.*, history.price
FROM collection
INNER JOIN h ON collection.itemid=h.id
INNER JOIN history ON collection.itemid=history.itemid 
AND (select history.date_itemid from history WHERE itemid=collection.itemid GROUP BY date_itemid DESC LIMIT 1)=history.date_itemid 
WHERE h.description LIKE '%Awesome%'
生产查询时间:181.140秒


这实际上是SQL中一个相当常见的问题,至少我觉得自己经常遇到这个问题。您要做的是联接一对多表,但只联接到该表中最新或最旧的记录

实现这一点的诀窍是对具有多条记录的表进行自左连接,指定外键,并且该id应大于或小于其他记录的id(或日期或您正在使用的任何内容)。然后在WHERE条件中,您只需添加一个条件,即左侧联接的表具有空id—它无法与较新的记录联接,因为它是最新的记录

在您的情况下,SQL应该如下所示:

SELECT h.*, collection.*, history.price
FROM collection
INNER JOIN h ON collection.itemid=h.id
INNER JOIN history ON collection.itemid=history.itemid 
-- left join history table again
LEFT JOIN history AS history2 ON history.itemid = history2.itemid AND history2.id > history.id
-- filter left join results to the most recent record
WHERE history2.id IS NULL
AND h.description LIKE '%Awesome%'

这是另一种剪切一个内部连接语句的方法

select h.*,his.date_itemid, his.price from history his
INNER JOIN h ON his.itemid=h.id
WHERE his.itemid IN (select itemid from collection) AND h.description LIKE '%Awesome%' and his.id IN (select max(id) from history group by history.itemid)

你可以在这里试试

我不确定这是否是你想要的,但我试一下 编辑:修改

   CREATE VIEW LatestDatesforIds
AS
SELECT
  MAX(`history`.`date_itemid`) AS `lastPriceDate`,
  MAX(`history`.`id`) AS `matchingId`
FROM `history`
GROUP BY `history`.`itemid`;  


CREATE VIEW MatchDatesToPrices
AS
SELECT
  `ldi`.`lastPriceDate` AS `lastPriceDate`,
  `ldi`.`matchingId` AS `matchingId`,
  `h`.`id` AS `id`,
  `h`.`itemid` AS `itemid`,
  `h`.`price` AS `price`,
  `h`.`date_itemid` AS `date_itemid`
FROM (`LatestDatesforIds` `ldi`
  JOIN `history` `h`
    ON ((`ldi`.`matchingId` = `h`.`id`)));

SELECT c.itemid,price,lastpriceDate,description
FROM collection c
INNER JOIN MatchDatesToPrices mp
     ON c.itemid = mp.itemid
INNER JOIN h ON c.itemid = h.id
这应该是有效的:

SELECT h.*, collection.*, history.price
FROM collection
INNER JOIN h ON collection.itemid=h.id
INNER JOIN(
SELECT a.*
  FROM history a
  INNER JOIN 
     ( SELECT itemid,MAX(date_itemid) max_date_itemid
         FROM history 
        GROUP BY itemid
     ) b ON b.itemid = a.itemid AND b.max_date_itemid = a.date_itemid
  ) AS history ON history.itemid = collection.itemid
WHERE h.description LIKE '%Awesome%'

我不知道这是否需要很多执行时间。请尝试一下,因为您的表中可能有更多数据,这将是一个很好的测试,以查看查询执行时间。

在如此小的数据集上测试速度很困难,但避免使用“分组方式”可能会加快速度。您可以尝试有条件地将历史记录表连接到它本身,而不是分组

e、 g

选择h.*、c.*、h1.price
从h
h1.itemid=h.id上的内部连接历史h1
h2上的左外部联接历史h2.itemid=h.id
和h1.date\u itemid
换这条线

AND h1.date_itemid < h2.date_itemid
和h1.date\u itemid

实际处理顺序索引字段(最好是唯一的)也会加快速度。e、 g.按id排序ASC

您能提供一些表格条目吗?或者甚至是一个SQLFIDLE?使用Datesub(Curdate(),INTERVAL 1 day)来获取最后一天如何?如果您的日期\项目编号是一个字符串(似乎是),则使用%。但正如Alex所问,我们需要更多关于表格的信息。按日期排序\u itemnumber DESC LIMIT 1,将获得最后一个条目。我将数据简化了很多。但我确实需要收集、h和历史数据。当我有当前日期的数据时,上面的查询工作100%完美。我已经更新了我的sql FIDLE。我犯了个错误。但是你现在可以看到我想要的结果了。但是如果您运行明天的查询(在明天的定价数据填充之前)。您将返回0个结果如果该itemid还没有历史记录会发生什么?我将使用这个逻辑,看看是否可以得到正确的结果。如果某个itemid没有历史记录,那么第一次内部连接到history将失败,您将无法得到该itemid的任何结果。我的history.id的实际索引列实际上是UUID v4。以上这些对我来说是行不通的:(如果您有一个带有记录创建的时间戳的时间戳列或整数列,您可以在ON条件下使用它。例如:
将历史作为history2 ON history.itemid=history2.itemid和history2.created>history.created
立即打开日期,但它花费了225.625秒,并且仍在获取。我要开始了今晚晚些时候再讨论这个概念,我会让你知道结果的时间。我感觉我从集合中提取了更多数据,我无法将其删除。@AndrewWilson请尝试一下,因为您的表中可能有更多数据,这将是一个很好的测试,以查看查询执行时间。这不会返回所需的数据。这就是o如果您的查询不正确,请回答。@AndrewWilson我想您想得到每件商品的最后价格……所以请看一下这个,谢谢!您的查询比其他查询快得多。您能解释一下您的逻辑吗?
SELECT h.*, c.*, h1.price
FROM h


INNER JOIN history h1 ON h1.itemid = h.id
LEFT OUTER JOIN history h2 ON h2.itemid = h.id
    AND h1.date_itemid < h2.date_itemid
INNER JOIN collection c ON c.itemid = h.id

WHERE h2.id IS NULL
AND h.description LIKE '%Awesome%'
AND h1.date_itemid < h2.date_itemid