简体   繁体   English

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

[英]Mysql query inner join on most recent date (today, yesterday, or before)

I'm attempting to pull the latest pricing data from a table on an Inner Join. 我正试图从内部联接的表中提取最新的定价数据。 Prices get updated throughout the day but aren't necessary updated at midnight. 价格全天更新,但无需在午夜更新。

The following query works great when the data is updated on prices by the end of the day. 当数据在当天结束时更新时,以下查询非常有用。 But how do I get it to get yesterdays data if today's data is blank? 但是,如果今天的数据是空白的,我如何得到昨天的数据呢?

I'm indexing off of a column that is formatted like this date_itemnumber => 2015-05-22_12341234 我正在索引一个格式如此date_itemnumber => 2015-05-22_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%'

Production Query time: .046 sec 生产查询时间:.046秒

To be clear, I want it to check for the most up to date record for that item. 为了清楚起见,我希望它检查该项目的最新记录。 Regardless on if it is today, yesterday or before that. 无论是今天,昨天还是之前。

SQLFiddle1 SQLFiddle1

The following query gives me the desired results but with my production dataset it takes over 3 minutes to return results. 以下查询为我提供了所需的结果,但使用我的生产数据集返回结果需要3分钟以上。 As my dataset gets larger, it would take longer. 随着我的数据集变大,需要更长的时间。 So this can't be the most efficient way to do this. 所以这不是最有效的方法。

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%'

Production Query time: 181.140 sec 生产查询时间:181.140秒

SQLFiddle2 SQLFiddle2

SELECT x.*
  FROM history x
  JOIN 
     ( SELECT itemid
            , MAX(date_itemid) max_date_itemid 
         FROM history 
  -- optional JOINS and WHERE here --
        GROUP
           BY itemid
     ) y
    ON y.itemid = x.itemid
   AND y.max_date_itemid = x.date_itemid;

http://sqlfiddle.com/#!9/975f5/13 http://sqlfiddle.com/#!9/975f5/13

This should works: 这应该有效:

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%'

I don't know if this take a lot of execution time. 我不知道这是否需要大量的执行时间。 Please do try it, since you might have more data in your tables it will be a good test to see the query execution time. 请尝试一下,因为您的表中可能有更多数据,这将是查看查询执行时间的一个很好的测试。

This is actually a fairly common problem in SQL, at least I feel like I run into it a lot. 这实际上是SQL中一个相当普遍的问题,至少我觉得我遇到了很多问题。 What you want to do is join a one to many table, but only join to the latest or oldest record in that table. 您要做的是加入一对多表,但只加入该表中的最新或最旧记录。

The trick to this is to do a self LEFT join on the table with many records, specifying the foreign key and also that the id should be greater or less than the other records' ids (or dates or whatever you're using). 这样做的诀窍是在表上使用许多记录进行自我LEFT连接,指定外键以及id应该大于或小于其他记录的ID(或日期或您正在使用的任何内容)。 Then in the WHERE conditions, you just add a condition that the left joined table has a NULL id - it wasn't able to be joined with a more recent record because it was the latest. 然后在WHERE条件中,您只需添加一个条件,左连接表具有NULL id - 它不能与更新的记录连接,因为它是最新的。

In your case the SQL should look something like this: 在您的情况下,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%'

This is another approach that cuts one inner join statement 这是另一种削减一个内连接语句的方法

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)

you can try it here http://sqlfiddle.com/#!9/837a8/1 你可以在这里试试http://sqlfiddle.com/#!9/837a8/1

I am not sure if this is what you want but i give it a try EDIT: modified 我不确定这是否是你想要的但是我试一试编辑:修改

   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

Difficult to test the speed on such a small dataset but avoiding 'Group By' might speed things up. 难以在如此小的数据集上测试速度,但避免“分组依据”可能会加快速度。 You could try conditionally joining the history table to itself instead of Grouping? 您可以尝试有条件地将历史表连接到自身而不是分组?

eg 例如

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%'

Changing this line 改变这一行

AND h1.date_itemid < h2.date_itemid

to actually work on a sequential indexed field (preferably unique) will speed things up too. 实际上在顺序索引字段(最好是唯一的)上工作也会加快速度。 eg order by id ASC 例如,通过id ASC订购

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM