我需要按两列排序数据,我该怎么做?
这是我的表:
Name | ImpFile | ImpTime
Sam Imp01 2012-05-16 09:54:02.477
Ann Imp01 2012-05-16 09:54:02.478
Mark Imp01 2012-05-16 09:54:02.477
John Import12 2012-05-16 09:55:37.384
Bart Import12 2012-05-16 09:55:37.387
Sasha Import12 2012-05-16 09:55:37.385
我需要按ImpTime和ImpName对此表进行排序,它应如下所示:
Name | ImpFile | ImpTime
Import12 2012-05-16 09:55:37.387
Bart Import12 2012-05-16 09:55:37.387
John Import12 2012-05-16 09:55:37.384
Sasha Import12 2012-05-16 09:55:37.385
Imp01 2012-05-16 09:54:02.478
Ann Imp01 2012-05-16 09:54:02.478
Mark Imp01 2012-05-16 09:54:02.477
Sam Imp01 2012-05-16 09:54:02.477
我正在使用此查询,但是当按时间为多行的相同值时,它不按名称对表进行排序,仅按名称排序。
select Name, ImpFile, ImpTime
from people
union
select distinct '', ImpFile, max(ImpTime)
from people
group by ImpFile
order by ImpTime desc, Name
这个查询给我这样的表:
Name | ImpFile | ImpTime
Import12 2012-05-16 09:55:37.387
John Import12 2012-05-16 09:55:37.384
Bart Import12 2012-05-16 09:55:37.387
Sasha Import12 2012-05-16 09:55:37.385
Imp01 2012-05-16 09:54:02.478
Sam Imp01 2012-05-16 09:54:02.477
Ann Imp01 2012-05-16 09:54:02.478
Mark Imp01 2012-05-16 09:54:02.477
有没有办法同时按这两列排序?
修改的
使用order by ImpFile DESC, ImpTime desc
时会发生什么?
它给了我一个像这样的结果表:
Name | ImpFile | ImpTime
Import12 2012-05-16 09:55:37.387
Imp01 2012-05-16 09:54:02.478
Bart Import12 2012-05-16 09:55:37.387
John Import12 2012-05-16 09:55:37.384
Sasha Import12 2012-05-16 09:55:37.385
Ann Imp01 2012-05-16 09:54:02.478
Mark Imp01 2012-05-16 09:54:02.477
Sam Imp01 2012-05-16 09:54:02.477
答案 0 :(得分:6)
为什么你能这样做:
order by ImpFile DESC, ImpTime desc
不,它不会导致你所展示的内容。结果如下:
Import12 2012-05-16 09:55:37.387
Bart Import12 2012-05-16 09:55:37.387
Sasha Import12 2012-05-16 09:55:37.387
John Import12 2012-05-16 09:55:37.383
Imp01 2012-05-16 09:54:02.477
Ann Imp01 2012-05-16 09:54:02.477
Mark Imp01 2012-05-16 09:54:02.477
Sam Imp01 2012-05-16 09:54:02.477
请参阅here以获取示例
修改强>
我有一个建议给你。也许是这样的:
测试数据
DECLARE @T TABLE(Name VARCHAR(100),ImpFile VARCHAR(100),ImpTime DATETIME)
INSERT INTO @T
([Name], [ImpFile], [ImpTime])
VALUES
('Sam', 'Imp01', '2012-05-16 09:54:02.477'),
('Ann', 'Imp01', '2012-05-16 09:54:02.478'),
('Mark', 'Imp01', '2012-05-16 09:54:02.477'),
('John', 'Import12', '2012-05-16 09:55:37.384'),
('Bart', 'Import12', '2012-05-16 09:55:37.387'),
('Sasha', 'Import12', '2012-05-16 09:55:37.385');
<强>查询强>
;WITH CTE
AS
(
SELECT
ROW_Number() OVER(PARTITION BY t.[ImpFile]
ORDER BY t.[ImpTime] DESC) AS RowNbr,
'' AS Name,
t.ImpFile,
t.[ImpTime]
FROM
@T AS t
)
SELECT
CTE.Name,
CTE.ImpFile,
CTE.[ImpTime],
0 as SortOrder
FROM
CTE
WHERE
CTE.RowNbr=1
UNION ALL
SELECT
t.Name,
t.ImpFile,
t.[ImpTime],
1 as SortOrder
FROM
@T AS t
ORDER BY
ImpFile DESC,SortOrder, ImpTime desc
答案 1 :(得分:5)
获取每个组的领导者并按降序时间对其进行排序:
with grp(Name,ImpFile,TimeGroup,ImpTime) as
(
select cast(null as varchar(5)), ImpFile, max(ImpTime) as TimeGroup,
max(ImpTime) as ImpTime
from people
group by ImpFile
)
select *
from grp
order by TimeGroup desc;
输出:
NAME IMPFILE TIMEGROUP IMPTIME
(null) Import12 2012-05-16 09:55:37.3870000 2012-05-16 09:55:37.3870000
(null) Imp01 2012-05-16 09:54:02.4780000 2012-05-16 09:54:02.4780000
然后将追随者加入领导者并获得领导者的时间(TimeGroup):
with grp(Name,ImpFile,TimeGroup,ImpTime) as
(
select cast(null as varchar(5)), ImpFile, max(ImpTime) as TimeGroup,
max(ImpTime) as ImpTime
from people
group by ImpFile
union all
select p.Name, p.ImpFile, ldr.TimeGroup, p.ImpTime
from people p
inner join grp ldr -- leader
on ldr.name is null and ldr.ImpFile = p.ImpFile
)
select Name, ImpFile, ImpTime
from grp
order by TimeGroup desc, Name
输出:
NAME IMPFILE IMPTIME
(null) Import12 2012-05-16 09:55:37.3870000
Bart Import12 2012-05-16 09:55:37.3870000
John Import12 2012-05-16 09:55:37.3840000
Sasha Import12 2012-05-16 09:55:37.3850000
(null) Imp01 2012-05-16 09:54:02.4780000
Ann Imp01 2012-05-16 09:54:02.4780000
Mark Imp01 2012-05-16 09:54:02.4770000
Sam Imp01 2012-05-16 09:54:02.4770000
查询的逻辑是,我们根据ImpFile将关注者(名字有些人)的时间与其领导者的时间(TimeGroup)对齐。领导者及其粉丝拥有相同的时间组,所以当我们按时间排序时,他们会互相依赖;然后,我们按名称排序
实时测试:http://www.sqlfiddle.com/#!3/c7859/21
如果我们希望小组组长出现在其关注者之后,只需在ORDER BY上提出一个案例:
with grp(Name,ImpFile,TimeGroup,ImpTime) as
(
select cast(null as varchar(5)), ImpFile, max(ImpTime) as TimeGroup,
max(ImpTime) as ImpTime
from people
group by ImpFile
union all
select p.Name, p.ImpFile, ldr.TimeGroup, p.ImpTime
from people p
inner join grp ldr -- leader
on ldr.name is null and ldr.ImpFile = p.ImpFile
)
select Name, ImpFile, ImpTime
from grp
order by TimeGroup desc,
case
when Name is null then 2 -- leader last
else 1 -- followers first
end,
Name
输出:
NAME IMPFILE IMPTIME
Bart Import12 2012-05-16 09:55:37.3870000
John Import12 2012-05-16 09:55:37.3840000
Sasha Import12 2012-05-16 09:55:37.3850000
(null) Import12 2012-05-16 09:55:37.3870000
Ann Imp01 2012-05-16 09:54:02.4780000
Mark Imp01 2012-05-16 09:54:02.4770000
Sam Imp01 2012-05-16 09:54:02.4770000
(null) Imp01 2012-05-16 09:54:02.4780000
实时测试:http://www.sqlfiddle.com/#!3/c7859/23
工作原理:
with grp(Name,ImpFile,TimeGroup,ImpTime) as
(
select cast(null as varchar(5)), ImpFile, max(ImpTime) as TimeGroup,
max(ImpTime) as ImpTime
from people
group by ImpFile
union all
select p.Name, p.ImpFile, ldr.TimeGroup, p.ImpTime
from people p
inner join grp ldr -- leader
on ldr.name is null and ldr.ImpFile = p.ImpFile
)
select *
from grp
order by TimeGroup desc, Name;
输出:
NAME IMPFILE IMPTIME TIMEGROUP
(null) Import12 2012-05-16 09:55:37.3870000 2012-05-16 09:55:37.3870000
Bart Import12 2012-05-16 09:55:37.3870000 2012-05-16 09:55:37.3870000
John Import12 2012-05-16 09:55:37.3840000 2012-05-16 09:55:37.3870000
Sasha Import12 2012-05-16 09:55:37.3850000 2012-05-16 09:55:37.3870000
(null) Imp01 2012-05-16 09:54:02.4780000 2012-05-16 09:54:02.4780000
Ann Imp01 2012-05-16 09:54:02.4780000 2012-05-16 09:54:02.4780000
Mark Imp01 2012-05-16 09:54:02.4770000 2012-05-16 09:54:02.4780000
Sam Imp01 2012-05-16 09:54:02.4770000 2012-05-16 09:54:02.4780000
答案 2 :(得分:2)
首先,您应该意识到,使用datetime
类型的粒度,SQL Server无法区分2012-05-16 09:55:37.384
和2012-05-16 09:55:37.385
:两者都将存储为2012-05-16 09:55:37.384
考虑到这一点并假设您希望按MAX(ImpTime) DESC
排序组以及按ImpTime DESC
排序详细信息行,您可以尝试这样的事情:
WITH agg AS (
SELECT
*,
ImpTimeMax = MAX(ImpTime) OVER (PARTITION BY ImpFile),
rn = ROW_NUMBER() OVER (PARTITION BY ImpFile ORDER BY ImpTime DESC)
FROM Table1
)
SELECT
Name = CASE x.IsAgg WHEN 1 THEN '' ELSE agg.Name END,
agg.ImpFile,
agg.ImpTime
FROM agg
INNER JOIN (SELECT 0 UNION ALL SELECT 1) x (IsAgg) ON x.IsAgg = 0 OR agg.rn = 1
ORDER BY
agg.ImpTimeMax DESC, /* the primary order for groups */
agg.ImpFile ASC , /* in case two or more groups have the same max time */
x.IsAgg DESC, /* the group summary row goes first */
agg.ImpTime DESC, /* or: agg.rn ASC */
agg.Name ASC /* in case two or more people have the same time */
运行on SQL Fiddle时,会为您的示例生成以下输出:
NAME IMPFILE IMPTIME
----- -------- -----------------------
Import12 2012-05-16 09:55:37.387
Bart Import12 2012-05-16 09:55:37.387
Sasha Import12 2012-05-16 09:55:37.385
John Import12 2012-05-16 09:55:37.384
Imp01 2012-05-16 09:54:02.478
Ann Imp01 2012-05-16 09:54:02.478
Mark Imp01 2012-05-16 09:54:02.477
Sam Imp01 2012-05-16 09:54:02.477
请注意,我暂时将ImpTime
定义为varchar
,而不是datetime
,只是为了更好地演示,因为,就像我说的那样,{{1}粒度会导致存储的值略有不同(因此产生的输出略有不同)。
答案 3 :(得分:1)
您可能想要擦除毫秒:http://www.sqlfiddle.com/#!3/35065/2
select Name, ImpFile,
ImpTimeX =
DATEADD(ms, -DATEPART(ms, ImpTime), ImpTime)
from tbl
union
select distinct '', ImpFile,
ImpTimeX =
MAX(DATEADD(ms, -DATEPART(ms, ImpTime), ImpTime))
from tbl
group by ImpFile
order by ImpTimeX desc, Name
输出:
NAME IMPFILE IMPTIMEX
Import12 May, 16 2012 09:55:37-0700
Bart Import12 May, 16 2012 09:55:37-0700
John Import12 May, 16 2012 09:55:37-0700
Sasha Import12 May, 16 2012 09:55:37-0700
Imp01 May, 16 2012 09:54:02-0700
Ann Imp01 May, 16 2012 09:54:02-0700
Mark Imp01 May, 16 2012 09:54:02-0700
Sam Imp01 May, 16 2012 09:54:02-0700
用于清除此处输出的毫秒的技术:SQL Server remove milliseconds from datetime
如果您想保留并显示原始时间,请执行以下操作:http://www.sqlfiddle.com/#!3/35065/1
with a as(
select Name, ImpFile,
ImpTimeX =
DATEADD(ms, -DATEPART(ms, ImpTime), ImpTime),
ImpTime
from tbl
union
select distinct '', ImpFile,
ImpTimeX =
MAX(DATEADD(ms, -DATEPART(ms, ImpTime), ImpTime)),
MAX(ImpTime)
from tbl
group by ImpFile
)
select Name, ImpFile, ImpTime
from a
order by ImpTimeX desc, Name
我认为SqlFiddle没有显示毫秒。请在你的Sql Server上尝试第二个查询,我现在正在其他操作系统上,我看不到第二个查询的实际输出
这是第二个查询的输出,日期时间完整,在SSMS上测试:
Name ImpFile ImpTime
Import12 2012-05-16 09:55:37.3870000
Bart Import12 2012-05-16 09:55:37.3870000
John Import12 2012-05-16 09:55:37.3840000
Sasha Import12 2012-05-16 09:55:37.3850000
Imp01 2012-05-16 09:54:02.4780000
Ann Imp01 2012-05-16 09:54:02.4780000
Mark Imp01 2012-05-16 09:54:02.4770000
Sam Imp01 2012-05-16 09:54:02.4770000
答案 4 :(得分:0)
看起来order by
仅适用于select
查询中的第二个union
。
尝试使用subselect
创建临时表格以将order by
应用于:
select Name, ImpFile, ImpTime from (
select Name, ImpFile, ImpTime from people
union
select distinct '', ImpFile, max(ImpTime) from people group by ImpFile
) order by ImpTime desc, Name
答案 5 :(得分:0)
您可以通过ImpFile desc,Name
获得所需的输出select Name, ImpFile, ImpTime
from dbo.tbl_stack
union
select distinct '', ImpFile, max(ImpTime)
from dbo.tbl_stack
group by ImpFile
order by ImpFile desc,Name
这是输出
Name ImpFile ImpTime
Import12 2012-05-16 09:55:37.387
Bar Import12 2012-05-16 09:55:37.387
John Import12 2012-05-16 09:55:37.383
Sasha Import12 2012-05-16 09:55:37.387
Imp01 2012-05-16 09:54:02.477
Ann Imp01 2012-05-16 09:54:02.477
Mark Imp01 2012-05-16 09:54:02.477
Sam Imp01 2012-05-16 09:54:02.477