假设我有两个桌子。第一个表代表帐户,第二个表代表字符。表通过“ AccountId”列连接。根据游戏,字符连接到帐户,每个帐户可以包含4个字符。
在我的网站上,我有两个页面。第一页称为“ Characterlist.php”,并使用一个等于0的特定权限(帐户表中的列)生成游戏中的所有角色。
我正在使用此查询:
$query = "WITH
Acc AS
(SELECT AccountId, Authority
FROM Account
WHERE Authority = '0'),
Char AS
(SELECT Character.*
FROM Character, Acc
WHERE Character.AccountId = Acc.AccountId),
Res AS
(SELECT *,
ROW_NUMBER() OVER
(ORDER BY Reput DESC) AS row_number
FROM Char)
SELECT Res.Class,
Res.Name,
Res.Level,
Res.HeroLevel,
Res.Reput,
Res.row_number
FROM Res
WHERE Res.row_number >= '$charlistpagemin'
AND Res.row_number <= '$charlistpagemax'";
$ charlistpagemin和$ vharlistpagemax是我用来将整个字符列表分为几页的php变量。
当我搜索我的测试帐户的字符时,根据row_number()生成和排序的信誉的位置是可以的。
然后我有第二页userpanel.php,该页面仅显示给已签名的用户,使他们可以在另一个列表中看到他们的游戏角色。
我使用的查询几乎相同,但最终使用不同的规则。
$query =
"WITH
Acc AS
(SELECT AccountId,
Authority
FROM Account
WHERE Authority = '0'),
Char AS
(SELECT Character.*
FROM Character, Acc
WHERE Character.AccountId = Acc.AccountId),
Res AS
(SELECT *,
ROW_NUMBER()
OVER (ORDER BY Reput DESC) AS row_number FROM Char)
SELECT Res.AccountId,
Res.Class,
Res.Name,
Res.Level,
Res.HeroLevel,
Res.Reput,
Res.row_number
FROM Res
WHERE Res.AccountId = '" . $_SESSION["accountid"] . "'";
有问题。根据信誉,它们的位置与characterlist.php中的位置不同(不好)。问题出在哪里?
编辑: 表格“帐户”如下所示:
AccountId | Authority | ... |
“字符”表如下所示:
AccountId | Class | Name | Level | HeroLevel | Reput | ... |
我的测试帐户具有
AccountId: xxx | Authority: 0 | ... |
并且有字符
AccountId: XXX | Class: Dobrodruh | Name: Kryploij1 | Level: 15 | Herolevel: 0 | Reput: 0 | ... |
AccountId: XXX | Class: Dobrodruh | Name: Kryploid2 | Level: 15 | Herolevel: 0 | Reput: 0 | ... |
AccountId: XXX | Class: Dobrodruh | Name: Kryploij3 | Level: 15 | Herolevel: 0 | Reput: 0 | ... |
AccountId: XXX | Class: Dobrodruh | Name: Grakonecek<3 | Level: 15 | Herolevel: 0 | Reput: 0 | ... |
characterlist.php中显示的预期结果是
Position: 139 | Class: Dobrodruh | Name: Kryploij1 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 140 | Class: Dobrodruh | Name: Kryploid2 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 141 | Class: Dobrodruh | Name: Kryploij3 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 142 | Class: Dobrodruh | Name: Grakonecek<3 | Level: 15 | Herolevel: 0 | Reput: 0 |
但是userpanel.php的不良结果是:
Position: 110 | Class: Dobrodruh | Name: Kryploij1 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 111 | Class: Dobrodruh | Name: Kryploid2 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 112 | Class: Dobrodruh | Name: Kryploij3 | Level: 15 | Herolevel: 0 | Reput: 0 |
Position: 113 | Class: Dobrodruh | Name: Grakonecek<3 | Level: 15 | Herolevel: 0 | Reput: 0 |
简单来说,我的问题是用户面板的位置发生了变化。真实位置显示在字符列表中。为了根据信誉中表中的排序数据计算排名,我使用了查询中显示的row_number()函数。
答案 0 :(得分:1)
您的数据与reput
有联系,而您的row_number()
表达式为:
ROW_NUMBER() OVER (ORDER BY Reput DESC) AS row_number
在SQL中的订单是不稳定。这意味着具有联系的行以任意且不确定的顺序进行,并且该顺序可能从一个执行更改为另一个执行。
为什么排序不稳定?简单。 SQL表表示无序集,因此没有“基础”排序来定义在发生联系时发生的情况。
简单的解决方案是添加另一个密钥。对于您而言,我认为Name
可能就足够了:
ROW_NUMBER() OVER (ORDER BY Reput DESC, Name) AS row_number
答案 1 :(得分:0)
如果没有示例数据和输入,这真的很难回答,但是我认为是因为这两个查询执行不同的操作。
第一个查询将对结果进行分页,而分页则强加了顺序-首次加载页面时,$ charlistpagemin
和$ charlistpagemax
大概为0和10,因此得到前十个结果。
第二个查询没有排序-它只是结果列表(未定义顺序)。 如果您添加
order by Res.row_number desc
在查询末尾,它应该可以工作。