id| type | datetime |
---| ---------|--------------|
1 | admin | 2016-01-03 |
2 | user | 2016-01-07 |
3 | user | 2016-01-08 |
4 | admin | 2016-01-04 |
5 | user | 2016-01-01 |
6 | user | 2016-01-03 |
7 | user | 2016-01-05 |
8 | user | 2016-01-09 |
假设我上面有一张桌子,我需要根据日期时间重新排列。第一条记录必须来自admin,并且只有admin类型的最新日期时间。然后第二到第五条记录必须从用户类型中按日期时间降序排序。然后,第六条记录必须来自具有第二个最新日期时间的管理员类型。查询的预期结果如下表所示。
预期结果:
id| type | datetime |
---| ---------|--------------|
4 | admin | 2016-01-04 |
8 | user | 2016-01-09 |
3 | user | 2016-01-08 |
2 | user | 2016-01-07 |
1 | admin | 2016-01-03 |
7 | user | 2016-01-05 |
6 | user | 2016-01-03 |
5 | user | 2016-01-01 |
你们能告诉我如何编写查询以获得预期的结果吗?
答案 0 :(得分:3)
您可以在下面的示例中使用NTILE,它将行分为2组,然后您只需按组编号和日期时间对其进行排序:
SELECT id,
[type],
[datetime]
FROM (
SELECT id,
[type],
[datetime],
NTILE(2) OVER (ORDER BY [datetime] DESC) as NT
FROM YourTable
WHERE [type] = 'admin'
UNION ALL
SELECT id,
[type],
[datetime],
NTILE(2) OVER (ORDER BY [datetime] DESC) as NT
FROM YourTable
WHERE [type] = 'user'
) as p
ORDER BY NT, [type]
输出:
id type datetime
4 admin 2016-01-04
8 user 2016-01-09
3 user 2016-01-08
2 user 2016-01-07
1 admin 2016-01-03
7 user 2016-01-05
6 user 2016-01-03
5 user 2016-01-01
注意:如果您需要动态确定组号(f.e.基于行数),您可以使用:
DECLARE @i int
SELECT @i = --some number
NTILE(@i) OVER (ORDER BY ...
我建议使用:
SELECT @i = CAST(CASE WHEN COUNT(*)%4.00 = 1 THEN ROUND(COUNT(*)/4.00,0)+1 ELSE ROUND(COUNT(*)/4.00,0) END as int)
FROM YourTable
答案 1 :(得分:3)
如果您的计数不能完全被您想要分组的用户数量整除,我找到了一种方法,可以在没有NTILE
问题的情况下执行此操作。基于gofr1的脚本,我建议你使用它:
SELECT id,
[type],
[datetime]
FROM (
SELECT id,
[type],
[datetime],
ROW_NUMBER() OVER (ORDER BY [datetime]) - 1 Idx
FROM YourTable
WHERE [type] = 'admin'
UNION ALL
SELECT id,
[type],
[datetime],
FLOOR((ROW_NUMBER() OVER (ORDER BY [datetime]) - 1) / 3) Idx
FROM YourTable
WHERE [type] = 'user'
) as p
ORDER BY Idx, [type]