如何选择给定月份的最高价值?

时间:2018-11-20 16:28:08

标签: mysql

+-------------------------------------------------+-----------------+---------------------+
| landing_page                                    | all_impressions | dates               |
+-------------------------------------------------+-----------------+---------------------+
| https://www.example.co.uk/url-1                 |           53977 | 2018-08-19 13:59:40 |
| https://www.example.co.uk/url-1                 |             610 | 2018-09-19 13:59:40 |
| https://www.example.co.uk/url-1                 |            555  | 2018-10-19 13:59:40 |
| https://www.example.co.uk/url-1                 |            23   | 2018-11-19 13:59:40 |
| https://www.example.co.uk/                      |            1000 | 2018-06-19 13:59:40 |
| https://www.example.co.uk/                      |               2 | 2018-07-19 13:59:40 |
| https://www.example.co.uk/                      |               4 | 2018-08-19 13:59:40 |
| https://www.example.co.uk/                      |            1563 | 2018-09-19 13:59:40 |
| https://www.example.co.uk/                      |               1 | 2018-10-19 13:59:40 |
| https://www.example.co.uk/                      |            9812 | 2018-11-19 13:59:40 |
+-------------------------------------------------+-----------------+---------------------+

在上面的数据库表中,如果印象数是当前日期的最大值,我只想选择着陆页-例如,由此,选择将只返回https://www.example.co.uk/作为当月的all_impressions值是11月的最高值(https://www.example.co.uk/url-1因为它是8月的最高值,所以不会被选择)

我该如何使用SQL?

索引信息:

mysql> show indexes from landing_pages_client_v3;
+-------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                   | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| landing_pages_client_v3 |          0 | PRIMARY      |            1 | id          | A         |    24279939 |     NULL | NULL   |      | BTREE      |         |               |
| landing_pages_client_v3 |          1 | profile_id   |            1 | profile_id  | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| landing_pages_client_v3 |          1 | profile_id   |            2 | dates       | A         |          17 |     NULL | NULL   |      | BTREE      |         |               |
| landing_pages_client_v3 |          1 | profile_id_2 |            1 | profile_id  | A         |          17 |     NULL | NULL   | YES  | BTREE      |         |               |
| landing_pages_client_v3 |          1 | profile_id_2 |            2 | lp_id       | A         |     6069984 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

3 个答案:

答案 0 :(得分:2)

Derived Table中,对于每个all_impressions获得landing_page的最大值。返回主表以获取与最大all_impressions值对应的行。

只有当该行属于当前月份时,我们才会最终考虑该行。对于sargability,我们将不使用dates列上的函数。相反,我们将确定当前月份和下个月的第一天。我们将考虑属于该范围的dates。您可以在此处查看日期时间函数的详细信息:https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html

为了提高性能,您可能还需要添加以下复合索引:(landing_page, all_impressions, dates)。 (我不确定这些列应按哪个顺序排列。也许需要进行一些基准测试/试验。

SELECT
  t.* 
FROM 
  your_table AS t 
JOIN 
(
  SELECT
    landing_page, 
    MAX(all_impressions) AS max_all_impressions
  FROM your_table 
  GROUP BY landing_page
) AS dt 
  ON dt.landing_page = t.landing_page AND 
     dt.max_all_impressions = t.all_impressions 
WHERE 
 t.dates >= ((LAST_DAY(CURDATE()) + INTERVAL 1 DAY) - INTERVAL 1 MONTH) AND
 t.dates < (LAST_DAY(CURDATE()) + INTERVAL 1 DAY) 

答案 1 :(得分:0)

您可以尝试以这种方式选择landing_page的URL和all_impressions列的最大值。为此,您必须使用WHERE子句来检查您的dates列值是否与CURRENT_DATE编号相同 month year 。请参阅Date and Time Functions

SELECT landing_page,MAX(all_impressions) 
 FROM your_table_name_goes_here
WHERE MONTH(dates) = MONTH(CURRENT_DATE())
 AND YEAR(dates) = YEAR(CURRENT_DATE())

OR

SELECT landing_page
  FROM your_table_name_goes_here
WHERE MONTH(dates) = MONTH(CURRENT_DATE())
  AND YEAR(dates) = YEAR(CURRENT_DATE())
ORDER BY all_impressions DESC LIMIT 1

答案 2 :(得分:0)

在mysql中。你可以这样做。

SELECT landing_page,MAX(all_impressions) AS max_count
  FROM your_table_name_goes_here
    WHERE MONTH(dates) = MONTH(NOW()) AND YEAR(dates) = YEAR(NOW())
     GROUP BY landing_page ORDER BY max_count DESC LIMIT 1