如何在mysql中形成where子句?

pcww981p  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(259)

原来我有一个数据表是这样的:

┌─────────────────┬────────────────┬─────────────────────────┐
│ month (integer) │ year (integer) │ academic year (varchar) │
├─────────────────┼────────────────┼─────────────────────────┤
│ 1               │ 2018           │ 2017-2018               │
│ 12              │ 2018           │ 2017-2018               │
│ 3               │ 2019           │ 2018-2019               │
│ 3               │ 2019           │ 2015-2016               │
│ 8               │ 2019           │ 2018-2019               │
└─────────────────┴────────────────┴─────────────────────────┘

请注意不同的数据类型。
我的目标是获得这样的行:月份和年份形成一个属于同一行中学年的日期。学年从九月(9日)开始,到八月(8日)结束。例如,第三排不应包含在结果中,因为12/2018不属于2017-2018,而是2018-2019。
我的 WHERE 子句应该类似于: CONVERT(varchar(10), year-1) + '-' + CONVERT(varchar(10), year) = academic_year 如果月份小于9,
以及 CONVERT(varchar(10), year) + '-' + CONVERT(varchar(10), year+1) = academic_year 否则。
当然这个代码没有意义。我需要知道:
如何在数据类型之间转换,
如何连接属性和常量。
有可能吗?你知道吗?

aemubtdh

aemubtdh1#

首先,转换 month 以及 year 实际的 date . 有很多方法可以处理你的数据。使用 concatmonth 以及 year 转换成mysql认为 date 是一个。

date( concat(year,"-",month,"-",1) ) as created_at;

这会变成 year 以及 month 从月初开始的单一日期。
然后分开 academic_year 分为两列。我们可以利用格式总是 YYYY-YYYY (您可以使用 where academic_year not rlike '^[0-9]{4}-[0-9]{4}$' )使用 left 以及 right 获取第一个和最后4个字符。

left(academic_year, 4), right(academic_year, 4)

把这些变成学年开始和结束的日期。

date( concat(left(academic_year, 4),"-","09","-","01") ) as start_period
date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period

现在你可以和 created_at , start_period ,和 end_period 使用 between 比较。

where created_at between start_period and end_period

把它们放在一起。。。

select
    date( concat(year,"-",month,"-",1) ) as created_at,
    date( concat(left(academic_year, 4),"-","09","-","01") ) as start_period,
    date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period
from stuff
where created_at between start_period, end_period;

请注意,在您完成了将查询转换为正确查询的工作之后,查询变得多么容易 date 类型。与其针对您的特定需求进行特殊的解析,不如将其规范化为真实的解析 date 类型并使用内置的mysql日期函数。
如果可能的话,您应该将模式更改为直接存储为 date 类型。它不仅使事情变得更简单,而且可以更快地为日期列编制索引以进行快速搜索。即使你做不到,最好看看这样的数据应该如何存储。
为了向后兼容,请保留旧列,如果必须的话,只需添加新列即可。

add column stuff created_at date not null;
add column stuff academic_year_start date not null;
add column stuff academic_year_end date not null;

填充新列。

update stuff
set created_at = date( concat(year,"-",month,"-",1) ),
    academic_year_start = date( concat(left(academic_year, 4),"-","09","-","01") ),
    academic_year_end   = date( concat(right(academic_year, 4),"-","08","-","31") ) as end_period

把索引放在上面。

create index stuff_created_at on stuff (created_at);
create index academic_year on stuff (academic_year_start, academic_year_end);

一旦完成了你的查询,任何类似的事情,都变得非常简单和快速。

select *
from stuff
where created_at between academic_year_start and academic_year_end;

因为一个学年的信息会被多次复制,所以第二个重新设计是将学年信息移到自己的表中,并将其作为外键引用。

相关问题