我正在学习mysql,我有2个表,我必须比较table1主键和table2主键,在成功匹配时我需要从table2得到日期最小值和最大值为此我尝试了这些命令,虽然我得到了结果但是如果有任何好办法处理这种情况,请告诉我。
日期格式是这样的
mysql> select sdate from table2
| 27-Apr-2000 11:50:00 AM |
| 27-Apr-2000 10:20:00 AM |
| 27-Apr-2000 08:30:00 AM |
| 20-Jan-1999 12:00:00 PM |
我试过的命令
mysql> select min(str_to_date(m.sdate,'%d-%M-%Y')) as date_min, max(str_to_date(m.sdate,'%d-%M-%Y')) as date_max from ( select distinct p.key1 as key1, p.key2 as key2 from table1 as p ) as T inner join table2 as m on T.key1 = m.key1 and T.key2 = m.key2 where m.sdate !='';
+------------+------------+
| date_min | date_max |
+------------+------------+
| 1989-02-24 | 2011-12-30 |
+------------+------------+
1 row in set, 11396 warnings (18.95 sec)
mysql> select min(str_to_date(m.sdate,'%d-%M-%Y')) as date_min, max(str_to_date(m.sdate,'%d-%M-%Y')) as date_max from ( select p.key1 as key1, p.key2 as key2 from table1 as p ) as T inner join table2 as m on T.key1 = m.key1 and T.key2 = m.key2 where m.sdate !='';
+------------+------------+
| date_min | date_max |
+------------+------------+
| 1989-02-24 | 2011-12-30 |
+------------+------------+
1 row in set, 11442 warnings (18.78 sec)
mysql> select min(str_to_date(m.sdate,'%d-%M-%Y')) as date_min, max(str_to_date(m.sdate,'%d-%M-%Y')) as date_max from table2 as m, table1 as p where p.key1 = m.key1 and p.key2 = m.key2 and m.sdate !='';
+------------+------------+
| date_min | date_max |
+------------+------------+
| 1989-02-24 | 2011-12-30 |
+------------+------------+
1 row in set, 11442 warnings (18.86 sec)
mysql>
答案 0 :(得分:2)
所有查询都无法在VARCHAR
sdate
列上有效使用索引(即范围扫描操作),因为该列已“包装”在查询中的函数中。为了获得此表单查询的最佳性能,理想情况下sdate
将是实际的MySQL DATETIME
或TIMESTAMP
数据类型,甚至是规范格式的VARCHAR
。如果是这种情况,优化器将能够有效地使用索引来快速定位“最小”和“最大”日期值,而无需为每个翻转行评估STR_TO_DATE
函数。 table,并且避免需要排序操作来定位从函数返回的“最小”和“最大”值。
将(半咆哮)放在一边......
在一般情况下,要获得与您的问题中前两个查询相同的结果,可以选择Gordon Linoff的答案中建议的形式查询。
(我们注意前两个查询包含key2=key1
谓词,第三个查询包含key2=key2
谓词。)
如果table2
中有大量行,并且这些行中的绝大多数都会“匹配”来自table1
的行,并且相对较少的不同(key1,key2)
} table2
中的值,如果(key1,key2)
中的table1
元组是唯一的或几乎唯一的,
这种形式的查询有可能表现得更好:
SELECT MIN(q.sdate_min) AS date_min
, MAX(q.sdate_max) AS date_max
FROM ( SELECT m.key1
, m.key2
, MIN(STR_TO_DATE(m.sdate,'%d-%M-%Y')) AS sdate_min
, MAX(STR_TO_DATE(m.sdate,'%d-%M-%Y')) AS sdate_max
FROM table2 m
GROUP
BY m.key1
, m.key2
) q
JOIN table1 t
ON t.key1 = q.key1
AND t.key2 = q.key2
要提高内联视图查询的效果,您需要table2
上的索引,其前导列为key1
和key2
(按任意顺序排列),还包括sdate
列。例如:
... ON table2 (key1, key2, sdate)
要提高JOIN
操作的效果,您需要table1
上的索引,key1
和key2
作为索引中的前导列。例如:
... ON table1 (key1,key2)
或
... ON table1 (key2,key1)
(这假设您将在第三个查询中使用表单的谓词,即key1 = key1和key2 = key ** 2 **
如果您将使用形式为key1 = key1和key2 = key ** 1 **的谓词,那么我们将相应地调整查询和索引。
答案 1 :(得分:1)
您可以尝试这种方法:
select min(str_to_date(m.sdate,'%d-%M-%Y')) as date_min,
max(str_to_date(m.sdate,'%d-%M-%Y')) as date_max
from table2 m
where exists (select 1
from table1 t
where t.key1 = m.key1 and t.key1 = m.key2
);
然后,在table1(key1, key2)
上创建一个索引以获得性能。