我有一个网格的基本数据库表
CREATE TABLE `grid` (
`id` int(10) unsigned NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`customers_id` int(10) unsigned NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`seen` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我正在尝试从网格中尚不存在的x和y值中获取。 (稍后将其用作插入的一部分的方式)我正在使用以下内容,但有时,它返回一组已经存在的坐标...
的PHP
private $_maxColumns = 144;
private $_maxRows = 90;
MySQL(在PHP中带有引号-因此变量周围用大括号括起来)
SELECT
CONCAT(
FLOOR( (RAND() * ( {$this->_maxColumns} - 1 + 1 ) ) + 1 ),
'-',
FLOOR( (RAND() * ( {$this->_maxRows} - 1 + 1 ) ) + 1 )
) as 'random'
FROM `grid`
WHERE 'random' NOT IN (
SELECT CONCAT( `x`, '-', `y` ) FROM `grid`
)
任何帮助深表感谢!
最佳答案
它返回现有值,因为您使过滤器完全错误:
WHERE 'random' NOT IN (
SELECT CONCAT( `x`, '-', `y` ) FROM `grid`
在where条件中,将字符串文字
'random'
与永远不会返回该值的子查询进行比较。在where子句中,无法过滤已计算字段,因为选择列表是在where子句之后求值的。您只能在hading子句中过滤这些字段,并删除random一词周围的语音标记:SELECT
CONCAT(
FLOOR( (RAND() * ( {$this->_maxColumns} - 1 + 1 ) ) + 1 ),
'-',
FLOOR( (RAND() * ( {$this->_maxRows} - 1 + 1 ) ) + 1 )
) as random
FROM `grid`
HAVING random NOT IN (
SELECT CONCAT( `x`, '-', `y` ) FROM `grid`
)
但是,上述查询有可能根本不返回任何行。我宁愿生成一个范围内不存在的坐标的列表,并随机选择其中一个。我将拥有一个具有所有可能的x-y对的辅助表,只需在where条件为null的网格表上进行左连接,然后使用
order by rand() limit 1
或从php中进行随机选择。