为了追求SQL启发性,我编写了一个快速的SEDE查询来显示RepAge和总体Rank。 br />
我尝试格式化,但感觉不对,我的(可能)过长的Age语句似乎也被错误格式化。确实存在吗?

我提到了一些参数,作为改进的想法(年龄范围和选择限制)。

评论

令我惊讶的是我没有出现在列表中,但是随后我看到您正在选择前150名并按年龄顺序进行排序。

令我惊讶的是我不在那个名单上,但是后来我意识到了。 ...这些天是孩子。...:-]

您发现16岁的这个网站将来会为您带来很多帮助(我希望我成为该网站的测试版时可以参与其中)。做得好。

您确实意识到很多用户没有生日设置,对吧?

@Mast,是的,如果用户选择设置它,那么他们会被标记。这不是一个确定的措施,它有我无法解决的限制。

#1 楼

一些东西,一些nitpicks,一些UX,一些可能是bug。 Lyle的杯子已经说过的内容也是我的答案的一部分,但首先要注意的是:


此查询很难使用,因为您可能想要所有东西
SEDE允许使用具有相当简单语法的参数来使用参数:

##name:type[?if optional, default value]##


替换所有魔幻数字可使我们:

SELECT TOP ##x:int?150##
 -- ...
WHERE User.Age IS NOT NULL AND Users.Reputation > ##minrep:int?150## AND User.Age <= ##age:int?30##


Nitpicks:

请注意,这已经大大扩展了单行WHERE。我真的很喜欢在单独的行中声明WHERE条件的查询,因为这样可以更轻松地处理它们。
其优点是每次都允许删除而不会遇到语法错误。

可能是错误的:


您的Limit By排序是。 ..歪斜?奇怪? ...这样的查询的目的很可能是基于信誉的统计信息时,您可以选择最年轻的用户并根据年龄进行限制。
按需付费:WHERE Rep > 150排除了具有150个代表的用户!
再说一次,关于rep的where子句似乎仍然无济于事...
如果删除它,有一种方法可以根据声誉切断大部分“非活动”用户群。通常在查询该表时,我会明确排除具有1和101代表的用户。这两个值是非活动状态的有力指标。

我的最终版本:

SELECT TOP ##x:int?150##
  ROW_NUMBER() OVER (ORDER BY Users.Reputation DESC) AS Rank
  , Users.Id as [User Link]
  , Users.Age
  , Users.Reputation as Rep
FROM Users
WHERE Users.Age <= ##age:int?30##
ORDER BY Rank ASC;


(也可在SEDE上获得)

评论


\ $ \ begingroup \ $
“领带”呢?也许不是“最高”排名的问题(排名第150和151的赔率具有相同的排名?),而是说最低排名的年轻人呢? (截至本文,2个人拥有100个人代表。2610个人拥有101个人代表。。。这将使“前5位最低”成为“胡扯”)
\ $ \ endgroup \ $
–WernerCD
2015年6月11日19:09



\ $ \ begingroup \ $
在没有声誉联系的前提下,排名是唯一的。要打破平局,您必须在OVER定义中按一个额外的列来排序
\ $ \ endgroup \ $
–Vogel612♦
2015年6月11日19:12

\ $ \ begingroup \ $
或者,就像您发布的答案中的变体一样,与领带一起使用:)我只是在四处学习而已。我只是补充说,“联系”可能是一个错误,取决于查询-很可能不是这种情况,但是有机会。
\ $ \ endgroup \ $
–WernerCD
2015年6月11日19:12



\ $ \ begingroup \ $
@WernerCD可以自己回答;)
\ $ \ endgroup \ $
–Vogel612♦
2015年6月11日19:20在

\ $ \ begingroup \ $
我认为并不需要一个完整的答案,因为它只是在向您的完整答案添加一个警告-关于平局和反向查询以显示“选择前5名”如何变成“选择前2000名”,因为说的领带:)
\ $ \ endgroup \ $
–WernerCD
15年6月11日在19:29

#2 楼

如果将查询写在首先按等级排序,然后按年龄排序的位置上,则会得到更好的结果,并且应该能够摆脱where语句的一部分,我认为这会使查询更快一些。

SELECT TOP 150 
ROW_NUMBER() OVER (ORDER BY Users.Reputation DESC) AS Rank,
  Users.Id as [User Link], 
  Users.Age,
  Users.Reputation as Rep
FROM Users
WHERE Users.Age <= 30
ORDER BY Rank ASC, Users.Age ASC


这样我就可以摆脱此查询中的两个Where语句。

30岁以下的顶级用户

您没有得到相同的结果,但是您得到了预期的结果。当我看到这个问题和查询,然后又执行查询时,就像大多数用户一样,我感到很惊讶,但是当查询描述为“年龄在前150名以下的用户”时,我得到的查询结果是您希望看到的30英寸

评论


\ $ \ begingroup \ $
这里的结果可能不匹配...
\ $ \ endgroup \ $
–Vogel612♦
2015年6月11日14:14

\ $ \ begingroup \ $
有趣的是,我的年龄在该列表中是错误的...真的很担心我发疯了,幸运的是Facebook保存了这一天。
\ $ \ endgroup \ $
– RobH
15年6月11日在14:28

#3 楼

如果不阅读代码,该查询的作用是不明显的。您应该在Stack Exchange Data Explorer中添加标题和描述。我还发现这些列的排列不合理:我希望


年龄(首先列出,因为这是您的主要排序键)
用户链接(看看我们在说谁)
Rep(有关刚刚确定的用户的更多信息)

Rep排名(有关信誉得分的其他信息)

“排名”本身也是如此模棱两可,因为它无法传达您对用户进行排名的方式。


如果要按信誉对用户进行排名,请使用可以很好地处理联系的RANK(),而不是ROW_NUMBER(),它会打断

因为此查询只涉及一个表,所以如果不使用Users.限定所有列名,则可读性更高。

无需检查Age IS NOT NULL,因为只有非空值才能满足Age <= 30