当我增加页面(例如 LIMIT 3,3 到 LIMIT 4,3)时,我的查询(以下两者)返回不一致的排序结果。请参阅下面的示例图像,并注意我有两个新项目,尽管仅将 FROM 索引更改了 1。
最糟糕的是,我无法始终如一地生成任何特定的排序顺序,除了第一组:LIMIT 0, 6。然后 LIMIT 6,6 和其他变体返回截然不同的结果。例如,如果我更改 WANT 值,我可以获得一组完全不同的项目。
示例: http ://trackauthoritymusic.com/wwwroot/images/pagination-error-proof.jpg
环境:
- 回声 mysql_get_server_info(); // 5.1.67-日志
- 回声 PHP_VERSION; // 5.4.14
- character_set_client == utf8
- character_set_connection == utf8
- character_set_database == utf8
- character_set_filesystem == 二进制
- character_set_results == utf8
- character_set_server == latin1
- character_set_system == utf8
- collation_connection == utf8_unicode_ci
- collation_database == utf8_unicode_ci
- collation_server == latin1_swedish_ci
- 我正在使用 codeigniter,但我使用的是下面看到的标准 sql。
- 在共享主机包上
查询:
SELECT S.*, G.* FROM games C LEFT JOIN songs T ON G.game_id = S.game_id WHERE G.game_status != 'deleted' and G.game_status != 'hidden' AND G.group_id = 1 GROUP BY G.game_id ORDER BY ISNULL(G.game_uploading_starts), G.game_listening_starts desc LIMIT 4, 3
SELECT S.*, G.* FROM games C LEFT JOIN songs T ON G.game_id = S.game_id WHERE G.game_status != 'deleted' and G.game_status != 'hidden' AND G.group_id = 1 GROUP BY G.game_id ORDER BY (CASE WHEN G.game_uploading_starts IS NULL then 1 ELSE 0 END), G.game_listening_starts desc LIMIT 4, 3
这两个查询都会产生不一致的排序结果,而不是两者之间的简单不同集合。
查询表架构:
DROP TABLE IF EXISTS `games`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `games` (
`game_id` mediumint(6) NOT NULL AUTO_INCREMENT,
`group_id` mediumint(6) NOT NULL,
`game_status` enum('playlist','game','compilation','halloffame','theme','deleted','hidden') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'hidden' COMMENT 'except deleted, this is not maintained at runtime, but on a cron job',
`game_title` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`game_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`game_author_id` mediumint(6) NOT NULL,
`game_ta_id` mediumint(6) DEFAULT NULL,
`game_winner_id` mediumint(6) DEFAULT NULL,
`song_id` mediumint(6) DEFAULT NULL COMMENT 'either first example or 1st place song if awarded already',
`game_buyin` int(11) DEFAULT NULL,
`game_minpool` int(11) DEFAULT NULL,
`game_rating_avg` tinyint(3) DEFAULT NULL,
`game_songs_per_user` tinyint(2) NOT NULL DEFAULT '1',
`game_uploading_starts` int(10) DEFAULT NULL,
`game_listening_starts` int(10) DEFAULT NULL,
`game_rating_starts` int(10) DEFAULT NULL,
`game_awarding_starts` int(10) DEFAULT NULL,
`game_uploading_ends` int(10) DEFAULT NULL,
`game_awarding_complete` int(10) DEFAULT NULL,
`game_created` int(10) NOT NULL,
`game_summary` varchar(2000) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`game_id`),
KEY `game_status` (`game_status`,`song_id`)
) ENGINE=MyISAM AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `songs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `songs` (
`song_id` mediumint(6) NOT NULL AUTO_INCREMENT,
`game_id` mediumint(6) NOT NULL,
`group_id` tinyint(3) NOT NULL,
`user_id` mediumint(6) NOT NULL,
`user_vendor_id` tinyint(1) DEFAULT NULL,
`receipt_id` mediumint(6) DEFAULT NULL,
`song_status` enum('example','game','playlist','compilation','deleted','winner') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'example',
`song_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`song_artist` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`song_album` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_released` smallint(4) DEFAULT NULL,
`song_genre` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_reason` varchar(2500) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_rating_avg` smallint(3) NOT NULL DEFAULT '0',
`song_adjusted_avg` decimal(5,2) NOT NULL DEFAULT '0.00',
`song_rated_count` mediumint(6) NOT NULL DEFAULT '0',
`win_rating` smallint(3) DEFAULT NULL,
`song_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`song_added` int(11) NOT NULL,
`song_order` int(4) DEFAULT NULL,
`song_dedication` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`song_id`),
KEY `game_id` (`game_id`),
KEY `user_id` (`user_id`),
KEY `song_status` (`song_status`)
) ENGINE=MyISAM AUTO_INCREMENT=305 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;