我有一个具有这种结构的表Provision : 和其他一些废话 我加载了一个名为tempTable的临时表,它具有相同的结构和相同的数据。 在尝试之前,我正在尝试Provision表中的neID是一个varchar字段。 与集合不同的值被删除。 (我以前这样做过没有问题。) 既不是这个: ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
因此,我正在编写一个临时表,该表根据DESC
顺序中的total_points
设置position
,即IE用户拥有的积分越多,他们的排名就越高。
我还将从该表中选择一个subscriber_id
,以获取给定用户的当前position
但是,我遇到了很多奇怪的问题,这是我的代码:
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的所有account_types
,但是无论何时我将其添加到subscribers_points
WHERE子句中,我的表都不再基于total_points
给出position
,而是按subscriber_id
给出position
,这对我来说很奇怪,对我来说没有意义。
为了澄清起见,表subscribers
包含account_type
字段。 subscriber_points
表包含total_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
值与位置一起排序。 因此,将那些位置值与匹配的记录粘合在一起的任何方法都是...奇怪的。
好的,我找到了解决方案,但是它基本上包括创建2个临时表,以便在同一位置获得我想要的确切值,然后运行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`;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.