我正在使用堆栈交换数据资源管理器来学习SQL,但我认为这个问题的基本原理适用于其他数据库。
我正在查询Badges表,根据Stexdex (从现在起我将这样称呼它),它有以下模式:
这对于像[Epic]和[Legendary]这样有着独特名字的徽章很有效,但是银和金标记特有的徽章似乎是通过相同的确切名称混合在一起的。
下面是我为[mysql]标记编写的一个示例查询:
SELECT
UserId as [User Link],
Date
FROM
Badges
Where
Name = 'mysql'
Order By
Date ASC(略带注释的)输出是:如stexdex所见
User Link Date
--------------- ------------------- // all for silver except where noted
Bill Karwin 2009-02-20 11:00:25
Quassnoi 2009-06-01 10:00:16
Greg 2009-10-22 10:00:25
Quassnoi 2009-10-31 10:00:24 // for gold
Bill Karwin 2009-11-23 11:00:30 // for gold
cletus 2010-01-01 11:00:23
OMG Ponies 2010-01-03 11:00:48
Pascal MARTIN 2010-02-17 11:00:29
Mark Byers 2010-04-07 10:00:35
Daniel Vassallo 2010-05-14 10:00:38 这与目前的银牌和黄金收入者名单是一致的,但以更永恒的方式来说,截至2010年5月底,只有2名用户获得了[mysql]的黄金标签: Quassnoi和Bill。从以上结果可以看出,他们的名字是唯一出现两次的。
所以我就是这么理解的:
Id第一次出现(按时间顺序排列)是为了银徽章。现在,上述结果将银和金项目混合在一起。我的问题是:
GROUP BY Id并以某种方式选择Date的最小/最大值或第一个/秒?
- Is it perhaps more typical to do two totally separate queries instead?
- What is this idiom called? A row "partitioning" query to put them into "buckets" or something?
需求澄清
最初,我希望得到以下输出,本质上是:
User Link Date
--------------- -------------------
Bill Karwin 2009-02-20 11:00:25 // result of query for silver
Quassnoi 2009-06-01 10:00:16 // :
Greg 2009-10-22 10:00:25 // :
cletus 2010-01-01 11:00:23 // :
OMG Ponies 2010-01-03 11:00:48 // :
Pascal MARTIN 2010-02-17 11:00:29 // :
Mark Byers 2010-04-07 10:00:35 // :
Daniel Vassallo 2010-05-14 10:00:38 // :
------- maybe some sort of row separator here? can SQL do this? -------
Quassnoi 2009-10-31 10:00:24 // result of query for gold
Bill Karwin 2009-11-23 11:00:30 // :但是到目前为止,用一个单独的栏目来解释银和金也是很棒的,所以也可以自由地去追求这个角度。不过,我还是很好奇你会怎么做。
发布于 2010-06-06 18:59:21
这是一个典型的设计,还是有更友好的模式/规范化/不管你怎么称呼它?
当然,您可以添加类型代码以使其更加显式。但是,当你认为一个人不能在银牌之前得到一枚金徽章,那么日期戳就有了很大的区别。
在目前的设计中,您如何分别查询银牌和金章?按Id分组,以某种方式选择最小/最大值或第一个/秒?
是的-加入到派生表(AKA内联视图),这是一个用户列表&最低日期将返回银徽章。使用HAVING COUNT(*) >= 1也是可行的。您必须使用GROUP BY和COUNT(*) =2‘的组合才能获得金徽章--最大值日期并不能确保用户’d有多个记录.
您如何编写一个查询,先列出所有的银徽章,然后再列出所有的金徽章?
不好意思-被用户,还是所有银牌第一次,然后金牌?前者可以简单地通过使用ORDER BY t.userid, t.date来完成;后者我可能使用分析函数(IE: ROW_NUMBER(),秩()).
是否更典型的做法是执行两个完全独立的查询呢?
看看上面你的要求有多模糊,对我来说.
这个成语叫什么?行“分区”查询将它们放入“桶”或其他什么?
你要问的是以下同义词:分析,窗口,排名.
发布于 2010-06-06 19:05:31
你会做这样的事情,只依赖于日期或总数中的计数。
可以说,查询后面跟着黄金的白银也是没有意义的,而是像这样并行地获取数据:
不幸的是,您还没有真正指定您想要的内容,但是聚合的一个很好的起点是用简单的英语表示它。
例如:“给我标签mysql每个用户的银和金徽章奖励日期”。这确实是:
SELECT
UserId as [User Link],
min(Date) as [Silver Date],
case when count(*) = 1 THEN NULL ELSE max(date) END
FROM
Badges
Where
Name = 'mysql'
group by
UserId
Order By
case when count(*) = 1 THEN NULL ELSE max(date) END DESC, min(Date)编辑,更新后:
您想要的输出不是真正的SQL:它是两个单独的记录集。分离器是禁止的。作为一种基于setb的操作,不存在“自然”顺序,因此引入了一种:
SELECT
UserId as [User Link],
min(Date) as [Date],
0 as dummyorder
FROM
Badges
Where
Name = 'mysql'
group by
UserId
union all
select
UserId as [User Link],
max(Date) as [Date],
1 as dummyorder
FROM
Badges
Where
Name = 'mysql'
group by
UserId
having
count(*) = 2
Order By
dummyorder, Datehttps://stackoverflow.com/questions/2985415
复制相似问题