初学者SQL问题:在Stack Exchange Data Explorer中查询金银标签
我正在使用来学习SQL,但我认为这个问题的基本原理适用于其他数据库 我试图查询初学者SQL问题:在Stack Exchange Data Explorer中查询金银标签,sql,analytic-functions,Sql,Analytic Functions,我正在使用来学习SQL,但我认为这个问题的基本原理适用于其他数据库 我试图查询徽章表,根据Stexdex(从现在起我将称其为)该表具有以下模式: 徽章 身份证 用户ID 名字 日期 这适用于具有唯一名称的徽章,如[Epic]和[Legendary],但银牌和金牌专用徽章似乎因具有相同的确切名称而混合在一起 下面是我为[mysql]标记编写的一个查询示例: SELECT UserId as [User Link], Date FROM Badges Where Name =
徽章
表,根据Stexdex(从现在起我将称其为)该表具有以下模式:
- 徽章
- 身份证
- 用户ID
- 名字
- 日期
[Epic]
和[Legendary]
,但银牌和金牌专用徽章似乎因具有相同的确切名称而混合在一起
下面是我为[mysql]
标记编写的一个查询示例:
SELECT
UserId as [User Link],
Date
FROM
Badges
Where
Name = 'mysql'
Order By
Date ASC
(略加注释)输出为:
这与本文撰写之时的当前用户和收入者列表一致,但更永恒的说法是,截至2010年5月底,只有2名用户获得了金牌[mysql]
标签:Quassnoi和Bill Karwin,上述结果表明,他们的名字是唯一出现两次的
这就是我对它的理解:
第一次出现(按时间顺序)是指银徽章Id
- 第二次是为了黄金
- 这是一个典型的设计,还是有更友好的模式/规范化/不管你怎么称呼它
- 在当前的设计中,您将如何分别查询银徽章和金徽章?
并根据按Id分组
选择最小/最大值或第一/秒日期
- 如何编写一个查询,首先列出所有的银徽章,然后再列出所有的金徽章?
- 再想象一下,“真实”查询可能更复杂,即不只是按日期列出
- 您将如何编写它,以使白银子查询和黄金子查询之间不会有太多重复
- 用两个完全不同的查询来代替是不是更为典型
- 这个成语叫什么?一个行“分区”查询,将它们放入“bucket”还是什么
需求澄清 最初,我需要以下输出,基本上是:
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 // :
但是到目前为止,关于白银和黄金的单独专栏给出的答案也很好,所以也可以从这个角度进行探讨。不过,我还是很好奇你会怎么做
这是一个典型的设计,还是有更友好的模式/规范化/不管你怎么称呼它
当然,您可以添加类型代码以使其更显式。但是当你认为不能在银币前拿到一枚金质徽章时,日期戳对区分它们有很大的意义。
在当前的设计中,您将如何分别查询银徽章和金徽章?按Id分组并按日期选择最小/最大值或第一/第二
是-加入一个派生表(也称为内联视图),该表是一个用户列表&最短日期将返回银徽章。使用计数(*)大于等于1的也可以。您必须使用GROUP BY和COUNT(*)=2`组合才能获得金徽章-最大日期不能确保一个用户ID有多个记录
如何编写一个查询,首先列出所有的银徽章,然后再列出所有的金徽章
抱歉-由用户,或所有的银牌先,然后金牌?前者可以简单地通过使用t.userid、t.date
进行排序;后者我可能会使用分析函数(即:ROW_NUMBER(),RANK())
用两个完全不同的查询来代替是不是更为典型
看看上面关于你的要求有多模糊,对我来说无论如何
这个成语叫什么?一个行“分区”查询,将它们放入“bucket”还是什么
你所问的是以下同义词:分析、窗口、排名……你可以这样做,只依赖于聚合中的日期或计数 可以说,先查询白银再查询黄金也毫无意义,而是像这样并排获取数据: 不幸的是,您还没有真正指定您想要什么,但是聚合的一个好的起点是用简单的英语表达它 示例:“为每个用户提供标记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, Date
更进一步:这不属于meta!这真是一个SQL问题+1.很好的方法,银和金作为不同的列!这比我想的要好得多(即重新排列行)。
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, Date