Mysql虚拟列在何处

Mysql虚拟列在何处,mysql,Mysql,我有以下MySQL查询: SELECT from_unixtime( `lastlogin` ) AS `last` FROM `players` WHERE `lastlogin` <> 0 AND `last` < '2012-10-01 00:00:00'; 我得到以下结果: 1054-where子句中的未知列“last” last不能在WHERE语句中使用,因为它当然是一个虚拟列,并且不存在。lastlogin包含一个UNIX时间戳 但是,在where语句中使用虚拟列

我有以下MySQL查询:

SELECT from_unixtime( `lastlogin` ) AS `last`
FROM `players` WHERE `lastlogin` <> 0 AND `last` < '2012-10-01 00:00:00';
我得到以下结果:

1054-where子句中的未知列“last” last不能在WHERE语句中使用,因为它当然是一个虚拟列,并且不存在。lastlogin包含一个UNIX时间戳

但是,在where语句中使用虚拟列有正确的方法吗

谢谢您的帮助。

这应该可以:

SELECT a.`last`
FROM   (SELECT From_unixtime(`lastlogin`) AS `last` 
        FROM   `players` 
        WHERE  `lastlogin` <> 0) a 
WHERE  a.`last` < '2012-10-01 00:00:00'; 

如果在子查询中定义列别名,则可以引用列别名,但这样做效率不高,因为子查询必须为所有行生成一个临时结果集,以便外部查询中的条件丢弃这些行。尽早将结果集减少到匹配行将更有效

如果lastlogin列为unixtime格式,则可以将其与WHERE子句中的常量表达式进行比较:

SELECT FROM_UNIXTIME( `lastlogin` ) AS `last`
FROM `players` WHERE `lastlogin` < UNIX_TIMESTAMP('2012-10-01 00:00:00');
这可以从该列上的索引中获益,并减少结果集的大小

我删除了上次登录名0,因为您无论如何都不应该存储零日期。如果您使用零作为特殊值,这意味着没有值,那么您应该使用NULL

重新注释:是的,正确的函数名为。感谢您的更正,我已经编辑了以上内容。

TL;博士

所选答案中的查询应该有效;对于平凡的集合,性能良好。但对于大型电视台,这将是一场精彩的演出

为了获得最佳性能,我们希望使用引用范围条件中的裸列n的查询。大概是这样的:

SELECT from_unixtime( `lastlogin` ) AS `last`
  FROM `players`
 WHERE `lastlogin` > 0
   AND `lastlogin` < UNIX_TIMESTAMP('2012-10-01 00:00:00')
其执行计划几乎等同于使用内联视图创建派生表,并对派生表运行SELECT,这从性能角度来看也是有问题的:

SELECT from_unixtime( `lastlogin` ) AS `last`
  FROM `players` WHERE `lastlogin` <> 0 
 HAVING `last` < '2012-10-01 00:00:00';
SELECT d.*
  FROM (
         SELECT from_unixtime( `lastlogin` ) AS `last`
         FROM `players` WHERE `lastlogin` <> 0 
       ) d
WHERE `last` < '2012-10-01 00:00:00';
如果lastlogin是一个INT,那么它应该是一个UNIX_TIMESTAMP函数,位于谓词中的date literal附近,而不是FROM_UNIXTIME。
SELECT from_unixtime( `lastlogin` ) AS `last`
  FROM `players`
 WHERE `lastlogin` <> 0
   AND `lastlogin` < UNIX_TIMESTAMP('2012-10-01 00:00:00')