mariadb SQL搜索-获取最大值日期的奇怪行为

twh00eeo  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(113)

所以我在PHPMyAdmin中对MariaDB运行查询,它一直工作得很好,直到我们进入新的一个月,对于我的生活,我看不到这个问题。该表采用以下格式作为示例,它包含到目前为止7月和8月的数据:
| 时间戳|一代|出口|
| --|--|--|
| 2023-08-01 23:00:00|四十三点四|十二点五|
用于返回2023年7月MAX值的SQL;

$sql_a = "SELECT DATE_FORMAT(`timestamp`, '%a %d %M') AS timestamp, `generation` FROM solar_generation WHERE `generation` = (SELECT MAX(`generation`) FROM solar_generation) AND MONTH(timestamp)= 7 AND YEAR(timestamp) = 2023";

这正是我所期望的输出:

Fri 07 July 43.0

如果我把SQL改成8月份

SELECT DATE_FORMAT(`timestamp`, '%a %d %M') AS timestamp, `generation` FROM solar_generation WHERE `generation` = (SELECT MAX(`generation`) FROM solar_generation) AND MONTH(timestamp)= 8 AND YEAR(timestamp) = 2023;

尽管表中有数据,但我得到以下结果:

MySQL returned an empty result set (i.e. zero rows)

如果运行以下查询:

SELECT MAX(`generation`) FROM solar_generation WHERE MONTH(timestamp)= 8 AND YEAR(timestamp) = 2023;

我得到了MAX生成,正如我所期望的8月,只要我开始构建查询以获取数据,它就停止返回数据?
我做错了什么,我只是假设相同的查询会工作,或者在第8个月暴露的查询中有缺陷?

o4tp2gmn

o4tp2gmn1#

我不使用MariaDB。
但这看起来很可疑:

SELECT DATE_FORMAT(`timestamp`, '%a %d %M') AS timestamp, `generation` 
FROM solar_generation 
WHERE `generation` = (SELECT MAX(`generation`) FROM solar_generation)     --> this
  AND MONTH(timestamp)= 8 
  AND YEAR(timestamp) = 2023;

基本上,它说:

  • 名为solar_generation的查询表
  • 查找该表中generation列值等于整个表中最大**generation值的所有行**
  • 很可能只有一行满足该条件,尽管可以有更多行共享相同的(max!)generation列值
  • 那么,在所有这些行中(只有一行?其中一些?)只获取月份为八月(和2023年)的数据
  • 显然,由于没有得到任何结果,最大的generation值不属于August(2023)

这是Oracle,但忽略这一事实;这只是为了说明我认为正在发生的事情:

SQL> select * from solar_generation;

TIMESTAMP  GENERATION
---------- ----------
13.07.2023         20
28.07.2023         99  --> this is MAX generation; July 2023
14.08.2023         50
24.08.2023         80

SQL> select max(generation) from solar_generation;

MAX(GENERATION)
---------------
             99   --> OK, that's it

现在,让我们选择所有满足条件的行:max generation和July:

SQL> select * from solar_generation
  2  where generation = (select max(generation) from solar_generation) --> this is 99
  3    and extract(month from timestamp) = 7;

TIMESTAMP  GENERATION
---------- ----------
28.07.2023         99

最大的一代和八月呢?

SQL> select * from solar_generation
  2  where generation = (select max(generation) from solar_generation) --> this is 99
  3    and extract(month from timestamp) = 8;

no rows selected

SQL>

没有行,因为generation = 99属于July。
我不知道你期望什么结果,因为你没有解释;如果是每月最大生成量,那么您可以这样做(还是Oracle;将其调整为MariaDB语法):

SQL> select to_char(timestamp, 'mm.yyyy') month,
  2    max(generation) max_generation
  3  from solar_generation
  4  group by to_char(timestamp, 'mm.yyyy');

MONTH   MAX_GENERATION
------- --------------
08.2023             80
07.2023             99

SQL>
aemubtdh

aemubtdh2#

Littlefoot提供的答案恰恰说明了问题所在。
最大值不属于8月份。
你需要对你的逻辑做一点改变。找出每个特定月份和年份的最大值。
对你来说是的,

SELECT DATE_FORMAT(`timestamp`, '%a %d %M') AS timestamp,
      `generation` 
FROM solar_generation
WHERE `generation` = (SELECT MAX(`generation`) 
                      FROM solar_generation where MONTH(timestamp)= 8 
                      AND YEAR(timestamp) = 2023
                     );

我建议使用with子句at更有性能,并且如果将来发生变化,也更容易适应。

with max_val_per_month as (
  select `timestamp`,
          `generation` ,
         row_number() over(partition by MONTH(timestamp),YEAR(timestamp) order by generation desc ) max_gen
  from solar_generation
  ) select  DATE_FORMAT(`timestamp`, '%a %d %M') AS timestamp,
            `generation` 
    from max_val_per_month
    where max_gen = 1 
    and  MONTH(timestamp) = 8
    and year(timestamp) = 2023

参见example

相关问题