获取临时表MySQL中的行位置
因此,我正在编写一个临时表,根据获取临时表MySQL中的行位置,mysql,sql,join,position,row,Mysql,Sql,Join,Position,Row,因此,我正在编写一个临时表,根据total_points以DESC顺序设置位置,即用户拥有的点数越多,排名就越高 我还将从此表中选择一个订户id,以获得给定用户的当前位置 但是,我遇到了很多奇怪的问题,下面是我的代码: SET @rownum := 0; SELECT t.`subscriber_id`, t.`total_points`, s.`account_type`, @rownum := @rownum + 1 AS `position` FROM `subscribers_poin
total_points
以DESC
顺序设置位置
,即用户拥有的点数越多,排名就越高
我还将从此表中选择一个订户id
,以获得给定用户的当前位置
但是,我遇到了很多奇怪的问题,下面是我的代码:
SET @rownum := 0;
SELECT t.`subscriber_id`,
t.`total_points`,
s.`account_type`,
@rownum := @rownum + 1 AS `position`
FROM `subscribers_points` t
LEFT JOIN (
SELECT `id`, `account_type`
FROM `subscribers`
) s
on s.`id` = t.`subscriber_id`
WHERE t.`year` = 2015
AND t.`month` = 1
ORDER BY t.`total_points` DESC
我想过滤掉所有的账户类型
,包括1、2和9,但只要我将其添加到订阅者积分
WHERE子句中,我的表就不再根据总积分
给出位置
,而是根据订阅者id
,这很奇怪,对我来说没有意义
为了澄清,表订户
包含账户类型
字段。subscriber\u points
表包含total\u points
字段
理想的桌子应该是这样的:
-------------------------------------------------------------
| subscriber_id | position | total_points | account_type |
-------------------------------------------------------------
| 52 | 1 | 10 | 7 |
| 125 | 2 | 8 | 4 |
| 87 | 3 | 9 | 3 |
| 12 | 4 | 5 | 6 |
| 45 | 5 | 2 | 4 |
-------------------------------------------------------------
提前感谢您MySQL在计算行间值方面不可靠: 具有6个连续值的基本简单表:
mysql> create table foo (x int);
mysql> insert into foo (x) values (0), (1), (2), (3), (4), (5);
mysql> set @pos := 0;
mysql> select @pos := @pos + 1, x from foo where x not in (2, 3);
+------------------+------+
| @pos := @pos + 1 | x |
+------------------+------+
| 1 | 0 |
| 2 | 1 |
| 3 | 4 |
| 4 | 5 |
+------------------+------+
一切看起来都很好。我们删除了两行,位置号是连续的,看起来MySQL不会正确地计算@pos更新,除非结果集中包含一行。但随后您会在系统中添加一些排序:
mysql> set @pos := 0;
mysql> select @pos := @pos + 1, x from foo where x not in (2, 3) order by x desc;
+------------------+------+
| @pos := @pos + 1 | x |
+------------------+------+
| 1 | 5 |
| 2 | 4 |
| 3 | 1 |
| 4 | 0 |
+------------------+------+
请注意,即使我们颠倒了行的顺序,位置仍然在增加。您可能认为,@pos+1
内容将在扫描表和包含/排除行时进行评估。但是没有。在包含行并进行排序之后,以某种方式完成
这意味着您的计算位置基本上与您在查询的其余部分中检索的值无关。但如果按位置排序,则更令人困惑:
mysql> set @pos := 0;
mysql> select @pos := @pos + 1 as pos, x from foo where x not in (2, 3) order by pos desc;
+------+------+
| pos | x |
+------+------+
| 4 | 5 |
| 3 | 4 |
| 2 | 1 |
| 1 | 0 |
+------+------+
x
值与位置一起排序。所以把这些位置值和匹配记录粘在一起的是。。。不可靠。好的,我找到了解决方案,但它基本上包括创建两个临时表,在同一个位置获得我想要的精确值,然后运行SELECT以获得给用户的正确排名
代码如下:
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_rank_table` AS(
SELECT p.`subscriber_id`, p.`total_points`, s.`account_type`
FROM `subscribers_points` p
LEFT JOIN `subscribers` s
ON s.`id` = p.`subscriber_id`
WHERE p.`year` = _year
AND p.`month` = _month
AND s.`account_type` BETWEEN 3 AND 8
AND `password_created` = 1
AND `verified` = 1
AND `active` = 1
ORDER BY p.`total_points` DESC
);
SET @rank=0;
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_rank_table_count` AS(
SELECT @rank:=@rank+1 AS `rank`, `subscriber_id`, `total_points`
FROM `temp_rank_table`
ORDER BY `total_points` DESC
);
#
SELECT t.`rank`, t.`subscriber_id`, t.`total_points`
FROM `temp_rank_table_count` t
WHERE `subscriber_id` = _subscriber_id;
DROP TABLE `temp_rank_table`;
DROP TABLE `temp_rank_table_count`;
结果集,但没有数据集。天才。