简体   繁体   English

SQL-根据值将行插入表中,然后确定表中的位置

[英]SQL- insert row into table based on value, then determine position in table

I have a website which records hours played of a certain videogame. 我有一个网站,记录某个电子游戏的播放时间。 The table currently holds the name and hours played of 20k players. 该表当前保存着2万名玩家的名字和游戏时间。 If a new user enters their information, how could I determine their position in the table? 如果有新用户输入他们的信息,我如何确定他们在表中的位置?

Ideally a method which is as easy as possible on the CPU so it can deal with bursts of traffic, and even if the table grows (I assume ORDER BY is not advised for very large table!?) 理想情况下,这种方法在CPU上尽可能地容易,这样它就可以处理突发流量,即使表增长了(我认为对于大表也不建议使用ORDER BY!)

For example, current table: 例如,当前表:

User // Hours played 用户//玩了几个小时
Bob // 54 鲍勃// 54
Dave // 584 戴夫// 584
Steven // 63 史蒂文// 63

New user is Andy, hours played 300. I simply want to get returned the value '2' as he is the second on the table, ordered by hours played descending. 新用户是Andy,玩的小时数为300。我只是想返回值“ 2”,因为他是桌上的第二个,按播放的小时数递减。

Thanks in advance! 提前致谢!

Your syntax will vary depending on the database server you use (MySQL versus Oracle versus Microsoft SQL Server), but all modern RDBMS's support indexes in some fashion. 语法会因所使用的数据库服务器(MySQL,Oracle,Microsoft SQL Server)而异,但是所有现代RDBMS的支持索引都以某种方式出现。 By constructing the appropriate index (and then tuning on appropriate hardware), an ORDER BY clause or windowing function is perfectly acceptable even on large tables. 通过构造适当的索引(然后在适当的硬件上进行调整),即使在大型表上,ORDER BY子句或窗口函数也是完全可以接受的。

You could achieve this by using the 'RANK' function:. 您可以使用“ RANK”功能来实现:

Here's a quick example of how it could work using Microsoft SQL Server: 这是一个如何使用Microsoft SQL Server的快速示例:

--Create an example of your table
CREATE TABLE #HoursPlayed
(
    vchName VARCHAR(255),
intHoursPlayed INT
)

--Add in the initial daa
INSERT #HoursPlayed VALUES ('Bob', 54), ('Dave', 584), ('Steven', 63)

--Now add in Andy
INSERT #HoursPlayed VALUES ('Andy', 300)

--Now see where Andy fits in the list ordered by hours played
SELECT RANK()OVER(ORDER BY hp.intHoursPlayed desc) Position, *
FROM #HoursPlayed hp

Andy will be returned as position '2' from the SELECT statement as he has the second highest number of hours played in the list of players. Andy将在SELECT语句中返回位置“ 2”,因为他在玩家列表中所玩的小时数排名第二。

The above syntax can easily be altered to return a single row and the position of the player in the overall list. 可以很容易地更改以上语法,以返回单行和播放器在整个列表中的位置。

To appease the user questioning the solution, here's the final query that you can use. 为了使用户对解决方案提出疑问,这是您可以使用的最终查询。 It will allow you to specify a single user and get there position in terms of hours played 它将允许您指定一个用户,并按照玩时数获得排名

SELECT *
FROM 
(
   SELECT RANK()OVER(ORDER BY intHoursPlayed desc) Position, *
   FROM #HoursPlayed
) hp
WHERE hp.vchName = 'Andy'

Note that using a subquery can be detrimental on large datasets. 请注意,使用子查询对大型数据集可能有害。

select count(1) + 1 as Place
from Players
where HoursPlayed > (select HoursPlayed from Players where UserName = @UserName)

if I understood you right, you have a simple table like this: 如果我理解正确,您将有一个简单的表格,如下所示:

Table(USRNAME, HOURS_PLAYED)

..and information in that table is as such: ..该表中的信息如下:

"Bob", 54
"Dave", 584
"Steven", 63

There is basically nothing wrong with this layout but if you want to retrieve the "position" from the database, you really should add another column with an unique value. 这种布局基本​​上没有错,但是如果您要从数据库中检索“位置”,则实际上应该添加具有唯一值的另一列。 This kind of columns are called primary keys . 这种列称为主键 Why should you use this? 为什么要使用这个? Because relational databases work best if you treat them like bags of marbles. 因为如果将关系数据库当作大理石袋一样对待,则关系数据库最有效。 You tell the database which data you want and the database engine finds it for you. 您告诉数据库所需的数据,然后数据库引擎为您找到它。 They are based on set theory . 它们基于集合论 So your new table should look something like this: 因此,您的新表应如下所示:

Table(ID, USRNAME, HOURS_PLAYED)
1, "Bob", 54
2, "Dave", 584
3, "Steven", 63

This would be the "correct" way of doing it or as it is usually phrased: the best-practice. 这将是这样做的“正确”方法,或者通常被表述为:最佳实践。

THAT SAID, there is a way, but I strongly advise against using it. 可以的,但是我强烈建议您不要使用它。 MS SQL and also other database engines incoroporate a concept of ROW_NUMBER(). MS SQL和其他数据库引擎不符合ROW_NUMBER()的概念。 When you SELECT data from table, the server retrieves it in a 2D table. 当您从表中SELECT数据时,服务器将在2D表中检索数据。 SQL engine is able to calculate the index (not necessarily the actual position in the table!!!) if the returned row. 如果返回的行,SQL引擎能够计算索引(不一定是表中的实际位置!!!) Please refer to this link: http://msdn.microsoft.com/en-us/library/ms186734.aspx . 请参考以下链接: http : //msdn.microsoft.com/en-us/library/ms186734.aspx

So imagine a query like this: 因此,想象这样的查询:

SELECT USRNAME, HOURS_PLAYED FROM Table WHERE USRNAME='Bob';

This query would return the correct record, but you dont know the position. 该查询将返回正确的记录,但是您不知道位置。 If you use an ID column, it would be simple. 如果您使用ID列,那将很简单。

SELECT ID, USRNAME, HOURS_PLAYED FROM Table WHERE USRNAME='Bob'; 

This query would return number 1. 该查询将返回数字1。

But please keep in mind that database engine doesn't care the position of the record. 但是请记住,数据库引擎不在乎记录的位置。 So there is no difference between ID=3 and ID=23454 for the database itself. 因此,数据库本身在ID = 3和ID = 23454之间没有区别。 Just a number without a semantic meaning. 只是一个没有语义含义的数字。

I suggest you read up on the database design basics and you will be able to solve the rest of your db-related problems fairly quickly. 我建议您阅读数据库设计基础知识,您将能够很快解决其余与数据库有关的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM