ISDATE() 相当于 MySQL

问题描述 投票:0回答:6

我有一行 SQL Server 代码,它采用“YYYYMMDD”列出的日期,其中 DD 为 00,并将 00 转换为 01,以便它可以与日期时间一起使用。我希望能够使用 MySQL 来实现它

适用于 SQL Server 的当前代码:

INSERT patentdb.Citation(PatentNo, Citation, CitedBy, CitationDate)
SELECT PatentNo, citation, WhoCitedThis, dt 
FROM 
(
  SELECT PatentNo, Citation, WhoCitedThis, dt = CASE
    WHEN CitationDate LIKE '%00' THEN INSERT (CitationDate, 8, 1, '1') 
    ELSE CitationDate 
  END 
  FROM patentdb.CitationSource
) AS x
WHERE ISDATE(dt) = 1;

但是 isdate 在 MySQL 中无效,我该怎么做才能解决这个问题?

mysql sql mysql-workbench
6个回答
23
投票

您可以尝试使用 STR_TO_DATE 函数。如果表达式不是日期、时间或日期时间,则返回

null

WHERE STR_TO_DATE(dt, '%d,%m,%Y') IS NOT NULL

21
投票

一种可能性,允许参数为字符串、整数或日期:

WHERE DAYNAME(dt) IS NOT NULL

这些有效日期返回“星期二”:

SELECT IFNULL(DAYNAME('2016-06-21 18:17:47') , '');
SELECT IFNULL(DAYNAME('2016-06-21') , '');

这些无效日期返回 ''(空字符串):

SELECT IFNULL(DAYNAME('0000-00-00 00:00:00') , '');
SELECT IFNULL(DAYNAME('2016-06-32 18:17:47') , '');
SELECT IFNULL(DAYNAME(NULL) , '');
SELECT IFNULL(DAYNAME(10) , '');

在 mysql 5.6 中,DAYNAME 似乎比 STR_TO_DATE 快 2 倍:

SELECT benchmark(10000000, DAYNAME('2016-06-21 18:17:47'))
1 row(s) returned   3.215 sec / 0.0000072 sec

SELECT benchmark(10000000, STR_TO_DATE('2016-06-21 18:17:47', '%d,%m,%Y'))
1 row(s) returned   7.905 sec / 0.0000081 sec

我认为如果参数是日期(而不是例如字符串),性能会更好。


1
投票

与 Timo Kähkönen 的答案类似,我使用 TIMESTAMPDIFF 来确定日期是否有效,就像 ISDATE 一样。我在两个日期参数中使用相同的日期。如果是日期则返回零,如果不是则返回 NULL。

我使用 BENCHMARK 运行了所有三个示例,其中包含有效和无效日期。我在 ISP JustHost 的共享服务器上运行此程序,MYSQL 版本 5.6.32-78.1:

SELECT benchmark(10000000, DAYNAME('2016-06-21 18:17:47'));
-- 1 row(s) returned   3.215 sec / 0.0000072 sec

Mine:  Query took 3.5333 seconds.

SELECT benchmark(10000000, STR_TO_DATE('2016-06-21 18:17:47', '%d,%m,%Y'));
-- 1 row(s) returned   7.905 sec / 0.0000081 sec

Mine: Query took 7.9635 seconds.

SELECT benchmark(10000000, TIMESTAMPDIFF(DAY,'2016-06-21 18:17:47','2016-06-21 18:17:47'));

Mine:  Query took 5.1373 seconds.

...........................

With bad date (June 41st?)

SELECT benchmark(10000000, DAYNAME('2016-06-41 18:17:47'));

Mine: Query took 7.3872 seconds.

SELECT benchmark(10000000, STR_TO_DATE('2016-06-41 18:17:47', '%d,%m,%Y'));

Mine: Query took 7.9919 seconds.

SELECT benchmark(10000000, TIMESTAMPDIFF(DAY,'2016-06-41 18:17:47','2016-06-41 18:17:47'));

Mine:  Query took 7.3792 seconds.

STR_TO_DATE 比其他两个稍慢。如果您主要使用有效日期,则 DAYNAME 方法似乎是最快的。但没有一个确实是一个糟糕的方法。


0
投票

您还可以使用以下

使用

REGEXP
'^([1-9]|0[1-9]|1[012])/([1-9]|0[1-9]|[12][0-9]|3[01])/(19|20)[0-9][0-9]'

但是正则表达式在这里可能很棘手,因为日期有太多不同的格式,

或者

转换 DATE,然后检查结果的长度,发现 null,然后不是日期。

length(DATE(mydate))


0
投票

我见过的许多解决方案都允许无效日期,例如“2023-02-30”或“2023-2-2”。

我使用日期函数和简单正则表达式的组合来验证 Mysql/MariaDB 中的日期:

SET @date = '2023-02-28';
SELECT DATE(STR_TO_DATE(@date, '%Y-%m-%d')) IS NOT NULL AND @date REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2}$';

结果是1

SET @date = '2023-02-29';

结果是0


-2
投票

好吧,虽然我很欣赏所有的说法,但我总是喜欢简单的方法。

所有日期戳中都包含“-”或“/”字符,所以为什么不使用 LIKE 参数检查所有包含此类字符的日期列。

SELECT * FROM TABLE WHERE DATE_COLUMN LIKE '%/%';
SELECT * FROM TABLE WHERE DATE_COLUMN LIKE '%-%';
© www.soinside.com 2019 - 2024. All rights reserved.