我有一个网格的基本数据库表

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中进行随机选择。

09-16 05:10