MySQL 查询以获取每个分类的最新和最便宜的商品

发布于 2024-10-08 19:30:56 字数 1471 浏览 0 评论 0原文

我有一个数据集,其中包含各种租车的价格。数据包括:

  • 汽车类别(紧凑型、小型货车、SUV 等)、
  • 租赁价格以及
  • 收集数据的日期。

我需要查询这些数据以获得每类最便宜的价格,但我还需要从数据库中的多个结果中选择最新的价格,即使最新的价格比旧的价格更贵。

例如,我可能有这样的数据:

  • 类别,价格,日期
  • suv,100,今天
  • suv,121,今天
  • suv,49,3 天前
  • 小型货车,89,昨天
  • 小型货车,120,昨天
  • 小型货车,100,昨天
  • 小型货车,91, 3 天前
  • 小型货车、77、3 天前

我想运行一个查询来获取以下数据:

  • suv、100、今天
  • 小型货车、89、昨天

如果我执行如下查询:

SELECT * FROM data
ORDER BY class, date DESC, price;

则每个类的最上面行包含正确的数据。我只需要知道如何让数据库仅返回这些行并丢弃其余行。

我正在使用一个相当严格锁定的 MySQL 数据库,并且创建临时表不是一个选项。

更新添加:

上面是正在运行的 reql 查询的高度简化版本。真正的查询确实跨多个表进行连接,看起来更像是这样:

SELECT hc.companyname AS supplier, 
sr.pricedetails AS price, 
sr.matchedsipp AS class,
sr.cardetails AS cardetails,
CAST(sj.jobdate AS DATE) AS jobdate 
FROM searchdetails sd 
STRAIGHT_JOIN searchresults sr ON (
    sd.taskid = sr.taskid 
    AND sd.locationid = sr.locationid 
    AND sd.jobid = sr.jobid 
    AND sd.companyid = sr.companyid
) 
JOIN hirecompanies hc ON sr.companyid = hc.companyid 
JOIN locations lc ON lc.locationid = sd.locationid 
JOIN searchjobs sj ON sr.jobid = sj.jobid 
WHERE DATE(sd.pudate) = '2010-12-28' 
AND DATE(sd.dodate) = '2011-01-04' 
AND hc.countrycode = 'GB' 
AND lc.iata = 'MAN';

pudate 是接送日期,dodate 是还车日期。所有时态数据都使用 DATETIME 字段存储。

I have a dataset that consists of prices for various rental cars. The data consists of:

  • Class of car (compact, minivan, suv etc),
  • Price of rental, and
  • date the data was collected.

I need to query this data to get the cheapest price per class, but I also need to select the most recent price from where there are several results in the database, even if the most recent one is more expensive than an older one.

For example I might have data like this:

  • Class, Price, Date
  • suv, 100, today
  • suv, 121, today
  • suv, 49, 3 days ago
  • minivan, 89, yesterday
  • minivan, 120, yesterday
  • minivan, 100, yesterday
  • minivan, 91, 3 days ago
  • minivan, 77, 3 days ago
  • etc

I want to run a query that will grab the following data:

  • suv, 100, today
  • minivan, 89, yesterday
  • etc

If I do a query such as:

SELECT * FROM data
ORDER BY class, date DESC, price;

then the topmost row per class contains the correct data. I just need to know how I can get the database to return only those rows and discard the rest.

I'm using a rather heavily locked down MySQL database, and creating temporary tables is not an option.

Updated to add:

The above is a highly simplified version of the reql query that's being run. The real query does joins across several tables and looks more like this:

SELECT hc.companyname AS supplier, 
sr.pricedetails AS price, 
sr.matchedsipp AS class,
sr.cardetails AS cardetails,
CAST(sj.jobdate AS DATE) AS jobdate 
FROM searchdetails sd 
STRAIGHT_JOIN searchresults sr ON (
    sd.taskid = sr.taskid 
    AND sd.locationid = sr.locationid 
    AND sd.jobid = sr.jobid 
    AND sd.companyid = sr.companyid
) 
JOIN hirecompanies hc ON sr.companyid = hc.companyid 
JOIN locations lc ON lc.locationid = sd.locationid 
JOIN searchjobs sj ON sr.jobid = sj.jobid 
WHERE DATE(sd.pudate) = '2010-12-28' 
AND DATE(sd.dodate) = '2011-01-04' 
AND hc.countrycode = 'GB' 
AND lc.iata = 'MAN';

pudate is pick-up date, and dodate is drop off date. All temporal data is stored using DATETIME fields.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓝眼睛不忧郁 2024-10-15 19:30:56

这应该会产生每种车辆类型的最近搜索日期的最低价格:

 SELECT * FROM data D1
   WHERE NOT EXISTS
      (SELECT * FROM data D2 WHERE D2.class = D1.class
                             AND (D2.date > D1.date 
                             OR (D2.date = D1.date AND D2.price < D1.price)))

您有多少数据(这对于大量数据来说不会特别有效)?

This should produce the lowest price for the most recent search date per vehicle type:

 SELECT * FROM data D1
   WHERE NOT EXISTS
      (SELECT * FROM data D2 WHERE D2.class = D1.class
                             AND (D2.date > D1.date 
                             OR (D2.date = D1.date AND D2.price < D1.price)))

How much data do you have (this will not be especially performant over a lot of data)?

夜夜流光相皎洁 2024-10-15 19:30:56

使用带有 LIMIT 1 的多个 SELECT,然后使用 UNION 怎么样?这样,您可以组合不同的 ORDER BY,但每个特定查询仍然只能获取 1 行。

How about using multiple SELECTs with a LIMIT 1, and then using a UNION? That way you can combine different ORDER BY's and still only get 1 row for each specific query.

抽个烟儿 2024-10-15 19:30:56

像这样的东西吗?

SELECT class, date, MIN(price) 
FROM data 
WHERE (class, date) IN 
    (SELECT class, MAX(date) FROM data GROUP BY class)

Something like this?

SELECT class, date, MIN(price) 
FROM data 
WHERE (class, date) IN 
    (SELECT class, MAX(date) FROM data GROUP BY class)
与之呼应 2024-10-15 19:30:56
SELECT  t.*
FROM    (
        SELECT  class, MAX(date) AS maxdate
        FROM    mytable
        GROUP BY
                class
        ) td
JOIN    mytable t
ON      t.id = 
        (
        SELECT  id
        FROM    mytable ti
        WHERE   ti.class = td.class
                AND ti.date = td.maxdate
        ORDER BY
                ti.class, ti.date, ti.price, ti.id
        LIMIT 1
        )

mytable(class、date、price、id) 上创建索引,以便快速运行。

SELECT  t.*
FROM    (
        SELECT  class, MAX(date) AS maxdate
        FROM    mytable
        GROUP BY
                class
        ) td
JOIN    mytable t
ON      t.id = 
        (
        SELECT  id
        FROM    mytable ti
        WHERE   ti.class = td.class
                AND ti.date = td.maxdate
        ORDER BY
                ti.class, ti.date, ti.price, ti.id
        LIMIT 1
        )

Create an index on mytable (class, date, price, id) for this to work fast.

暗恋未遂 2024-10-15 19:30:56

要获得每类的最新价格

SELECT
*,
FROM data
GROUP BY class
HAVING date=max(date)

最低价格将是相同的,除非

HAVING price=min(price)

然后,如果您想要最低价格,当超过一个有最新日期

HAVING date=max(date) AND price=min(price)

To get the latest price per class

SELECT
*,
FROM data
GROUP BY class
HAVING date=max(date)

Lowest price would be the same except

HAVING price=min(price)

And then if you want least price when more than one have the latest date

HAVING date=max(date) AND price=min(price)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文