简体   繁体   English

SQL MIN(值)匹配日期

[英]SQL MIN(value) matching date

Alright I have a table where I need to get the relevant date from a GROUP BY function... 好了,我有一个表格,我需要从GROUP BY函数中获取相关日期...

Here is a sample of the data:
min_price, day
140000     2010-09-26
130000     2010-09-27
154991     2010-10-08
143000     2010-10-09
156470     2010-10-10

I would like this result:
130000     2010-09-27
143000     2010-10-09

Here is the SQL I use:

SELECT MIN(min_price) AS low_price, min_price, day
FROM compress
WHERE item_name = '$item'
GROUP BY EXTRACT(MONTH FROM day), EXTRACT(YEAR FROM day)

Here is what I get:
130000     2010-09-26
143000     2010-10-08

As you can see, the dates don't match up with the min row value. 如您所见,日期与最小行值不匹配。 I need them to match up. 我需要他们配合。 What SQL can I use to get that result? 我可以使用哪种SQL来获得该结果?

Select C.min_price, C.day
From compress As C
Where C.item_name = '$item'
    And Exists  (
                Select 1
                From compress As C2
                Where C2.item_name = C.item_name
                    And Extract(Month From C2.day) = Extract(Month From C.day)
                    And Extract(Year From C2.day) = Extract(Year From C.day)
                Group By Extract(Month From C2.day), Extract(Year From C2.day)
                Having C.min_price = Min(C2.min_price)
                )

ADDITION 加成

MySQL is better with joins so here's a variant of the same query MySQL的联接更好,所以这是同一查询的变体

Select C.min_price, C.day
From compress As C
    Join    (
            Select C2.item_name
                , Extract(Month From C2.day) As ItemMonth
                , Extract(Year From C2.day) As ItemYear
                , Min(C2.min_price) As MinPrice
            From compress As C2
            Group By C2.item_num, Extract(Month From C2.day), Extract(Year From C2.day)
            ) As Z
        On Z.item_name = C.item_name
            And Z.ItemMonth = Extract(Month From C.day)
            And Z.ItemYear = Extract(Year From C.day)
            And Z.MinPrice = C.min_price
Where C.item_name = '$item'

What is really slowing down any variation is the calling of Extract on every row. 真正减慢任何变化的是在每一行上调用Extract。 If you had a calendar table containing a row for each date and a column for the month and year of the date and your calendar table covered the date ranges in your data, you could then do something like: 如果您有一个日历表,其中每个日期都包含一行,而该日期的月份和年份则包含一列,并且您的日历表涵盖了数据中的日期范围,那么您可以执行以下操作:

Select C.min_price, C.day
From compress As C
    Join Calendar As Cal
        On Cal.Date = C.Day
    Join    (
            Select C3.item_name
                , Cal3.Month, Cal3.Year
                , Min(C3.min_price) As MinPrice
            From compress As C3
                Join Calendar As Cal3
                    On Cal3.Date = C3.day
            Group By C3.item_num, Cal3.Month, Cal3.Year
            ) As Z
        On Z.item_name = C.Item_name
            An Z.Month = Cal.Month
            And Z.Year = Cal.Year
            And Z.MinPrice = C.min_price
Where C.item_name = '$item'
SELECT min_price AS low_price, min_price, day
FROM compress
WHERE item_name = '$item' AND min_price = MIN(min_price)
GROUP BY EXTRACT(MONTH FROM day), EXTRACT(YEAR FROM day)

This will then select the row where the min_price is the same as the MIN(min_price) 然后,将选择min_price与MIN(min_price)相同的行

Your SQL is not valid. 您的SQL无效。 When grouping, every column in the display list (that is not part of the group by expression) must be passed through an aggregate function, eg AVG(), MIN(), MAX() but you're just asking for "day". 分组时,显示列表中的每一列(不属于按表达式分组的一部分)都必须通过聚合函数传递,例如AVG(),MIN(),MAX(),但您只是要求“ day” 。

Please state in natural language (English) what you are trying to achieve. 请用自然语言(英语)说明您要达到的目标。 Your example is not perfectly clear. 您的例子并不十分清楚。

If I have understood the problem correctly, this should work... 如果我正确理解了问题,则应该可以...

mysql> select * from stack;
+-----------+------------+
| min_price | myday      |
+-----------+------------+
|    140000 | 2010-09-26 | 
|    130000 | 2010-09-27 | 
|    154991 | 2010-10-08 | 
|    143000 | 2010-10-09 | 
|    156470 | 2010-10-10 | 
+-----------+------------+
5 rows in set (0.00 sec)

mysql> select a.* from stack as a inner join 
    -> (select min(min_price) as my_price from stack group by extract(YEAR_MONTH from myday)) as b
    -> on a.min_price = b.my_price;
+-----------+------------+
| min_price | myday      |
+-----------+------------+
|    130000 | 2010-09-27 | 
|    143000 | 2010-10-09 | 
+-----------+------------+
2 rows in set (0.00 sec)

You will need to join on a primary key in order to avoid unexpected results. 您将需要加入主键,以避免意外的结果。 If the query is slow, create a temporary table for subselect, build indexes on it and then use the table to join with the main table. 如果查询速度慢,请为subselect创建一个临时表,在其上建立索引,然后使用该表与主表联接。

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

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