是否可以在SQL中按列排序而不是按行排序?我不需要基本的ORDER BY语句,我知道这些是如何工作的(即:按column1,column2等命令)。
基本上尝试对这样的事情进行排序:
column 1 column 2 column 3
1 0 3
试图对此进行排序:
column 3 column 1 column 2
3 1 0
这在SQL中是否可行?最好是t-sql或将在sql server 2005上运行的任何东西
我一直在网上搜索这几个小时,似乎没有人想问这个问题。或者我吮吸搜索。
; with numbered as
(
select SUM(OrderReceived) as c1, SUM(OrderOnHold) as c2, SUM(OrderConfirmed) as c3,
row_number() over (order by employee) RecordNumber
from( SELECT
e.FirstName+' '+e.LastName AS Employee
,CASE WHEN oim.MilestoneID = 10 THEN 1 ELSE 0 END as OrderReceived
,CASE WHEN oim.MilestoneID = 15 THEN 1 ELSE 0 END as OrderOnHold
,CASE WHEN oim.MilestoneID = 20 THEN 1 ELSE 0 END as OrderConfirmed
FROM OrderItems oi
JOIN Orders o on o.orderid = oi.orderid
JOIN OrderItemMilestones oim on oim.orderid = oi.orderid and oim.orderitemid = oi.orderitemid
JOIN Milestones m on m.milestoneid = oim.milestoneid
JOIN Employees e on e.username = oim.recordedbyuser
JOIN Clients cl on cl.clientid = o.clientid
WHERE oim.MilestoneDate Between '2012-08-01' and '2012-08-05'
and e.terminationdate is null
),
ordered as
(
select SUM(OrderReceived) as c1, SUM(OrderOnHold) as c2, SUM(OrderConfirmed) as c3,
row_number() over (partition by RecordNumber
order by employee desc) rn
from numbered
unpivot (v for c in (c1, c2, c3)) u
)
select RecordNumber,
[1] c1,
[2] c2,
[3] c3
from
(
select RecordNumber,
v,
Rn
from ordered
) o
pivot (min(employee) for Rn in ([1], [2], [3])) p
答案 0 :(得分:6)
这是对列进行排序的相对简单的方法。如果您首先unpivot,排序并pivot您的数据,您将获得排序列。
Here is Sql Fiddle with example
-- Assign arbitrary numbers to records
-- You might skip this part if you have unique column
-- in which case you should replace RecordNumber with this ID
; with numbered as
(
select *,
row_number() over (order by (select null)) RecordNumber
from test
),
-- Generate order by
-- For all the columns in record.
-- Rn will always be in range
-- 1..NumberOfColumns
-- Order is done on unpivoted data
ordered as
(
select *,
row_number() over (partition by RecordNumber
order by v desc) rn
from numbered
-- list all the columns here
-- v is for value
-- c is for column
unpivot (v for c in (c1, c2, c3)) u
)
-- Finally return the data in original layout
select RecordNumber,
[1] c1,
[2] c2,
[3] c3
from
(
-- Only the columns needed by the query
-- Pivot will not play nice even if you
-- Select only subset of columns in
-- outer query
select RecordNumber,
v,
Rn
from ordered
) o
-- Get value for row numbers 1..NumberOfColumns
pivot (min(v) for Rn in ([1], [2], [3])) p
您可能希望添加标题行,以便了解哪个值来自哪个列。要做到这一点,我会添加一个标识标题/行的列,将所有标题联合到o
以获取相应的标题和顺序,以确保这两行保持在一起:
(
select RecordNumber,
v,
Rn,
1 HdrRow
from ordered
union all
select RecordNumber,
c, -- Column name is in c
Rn,
0 HdrRow
from ordered
) o
...
order by RecordNumber, HdrRow
答案 1 :(得分:5)
您使用的是SELECT *
吗?如果是这样,请停止这样做。如果你知道你希望它们以这种方式列出,那么写下:
SELECT [column 3], [column 1], [column 2] FROM dbo.table;
如果你的意思是想要在这些列中进行排序,我不确定它会有多么有意义。但我猜你可以这样做:
DECLARE @x TABLE(c1 INT, c2 INT, c3 INT);
INSERT @x(c1,c2,c3) SELECT 2,1,3
UNION ALL SELECT 3,4,5
UNION ALL SELECT 5,4,3
UNION ALL SELECT 3,1,2
UNION ALL SELECT 3,3,3
UNION ALL SELECT 3,4,3
UNION ALL SELECT 4,3,4;
SELECT c1 = CASE
WHEN c1 >= c2 AND c1 >= c3 THEN c1
WHEN c2 >= c1 AND c2 >= c3 THEN c2
ELSE c3 END,
c2 = CASE
WHEN c1 >= c2 AND c1 >= c3 THEN
CASE WHEN c2 >= c3 THEN c2 ELSE c3 END
WHEN c2 >= c1 AND c2 >= c3 THEN
CASE WHEN c1 >= c3 THEN c1 ELSE c3 END
ELSE
CASE WHEN c1 >= c2 THEN c1 ELSE c2 END
END,
c3 = CASE
WHEN c1 <= c2 AND c1 <= c3 THEN c1
WHEN c2 <= c1 AND c2 <= c3 THEN c2
ELSE c3 END
FROM @x;
结果:
c1 c2 c3
---- ---- ----
3 2 1
5 4 3
5 4 3
3 2 1
3 3 3
4 3 3
4 4 3
答案 2 :(得分:0)
如果您的查询只返回一行,那么您可以通过执行两次查询来解决此问题:
如果您的查询应该返回多行数据,我想我们需要更多信息,您需要提供一些可行的解决方案,或者至少是一个更好的建议如何缓解您的问题。< / p>