我正在使用SQL Server 2014
,下面的表格(t1
)包含大约5,000行。
这是t1
的摘录:
n1 n2 n3 n4 n5 n6 Type
6 15 10 11 22 25 C1
2 5 1 20 21 30 C1
15 25 18 4 12 38 C2
11 1 4 9 24 31 C2
...
我需要从表中选择所有行,但是我希望输出以升序排列。
这是预期的输出:
Nr1 Nr2 Nr3 Nr4 Nr5 Nr6 Type
6 10 11 15 22 25 C1
1 2 5 20 21 30 C1
4 12 15 18 25 38 C2
1 4 9 11 24 31 C2
...
我知道如何ORDER BY
列,但是对于如何解决此问题我完全陷于困境。我是否需要pivot
数据,对其进行排序然后再取消数据透视以实现此目的?
注意:我已将ID列添加到我的列中。现在每一行都有一个唯一的ID(1,2,3,...)
我根据Menno解决方案进行的尝试:
;with cte1 as (
SELECT [id], [type], Col, Val
FROM (
SELECT [id], [n1], [n2], [n3], [n4], [n5], [n6], [type]
FROM [t1] ) t
UNPIVOT
(Col FOR Val IN ([n1], [n2], [n3], [n4], [n5], [n6]))
AS tblUnPivot
),
cte2 as (
Select
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Val) OrderedVals, *
from [cte1]
),
cte3 as (
SELECT [id], [type], Col, Val
FROM (
SELECT [OrderedVals], [id], [type], [Col]
FROM [cte2] ) s
PIVOT
(??? FOR OrderedVals IN ([1],[2],[3],[4],[5],[6]))
AS tblPivot
)
select * from [cte3]
答案 0 :(得分:4)
假定,其中有某种ID列,然后您可以取消透视值,然后使用VALUES
和一个交叉表将其透视回去:
CREATE TABLE dbo.YourTable (ID int IDENTITY, --Required to work
n1 tinyint,
n2 tinyint,
n3 tinyint,
n4 tinyint,
n5 tinyint,
n6 tinyint,
[Type] char(2));
GO
INSERT INTO dbo.YourTable (n1,n2, n3, n4, n5, n6, [Type])
VALUES( 6,15,10,11,22,25,'C1'),
( 2, 5, 1,20,21,30,'C1'),
(15,25,18, 4,12,38,'C2'),
(11, 1, 4, 9,24,31,'C2');
GO
SELECT *
FROM dbo.YourTable;
WITH unPvt AS (
SELECT YT.ID,
YT.[Type],
V.Val,
ROW_NUMBER() OVER (PARTITION BY YT.ID ORDER BY V.Val) AS NewPos
FROM dbo.YourTable YT
CROSS APPLY (VALUES(1,YT.n1),
(2,YT.n2),
(3,YT.n3),
(4,YT.n4),
(5,YT.n5),
(6,YT.n6))V(Pos,Val))
SELECT MAX(CASE NewPos WHEN 1 THEN Val END) AS n1,
MAX(CASE NewPos WHEN 2 THEN Val END) AS n2,
MAX(CASE NewPos WHEN 3 THEN Val END) AS n3,
MAX(CASE NewPos WHEN 4 THEN Val END) AS n4,
MAX(CASE NewPos WHEN 5 THEN Val END) AS n5,
MAX(CASE NewPos WHEN 6 THEN Val END) AS n6,
[Type]
FROM unPvt
GROUP BY ID,[Type]
ORDER BY [Type];
GO
DROP TABLE dbo.YourTable;
答案 1 :(得分:1)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) ID
Col FOR Val IN ([Nr1], [Nr2], [Nr3], [Nr4], [Nr5], [Nr 6])
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Val) OrderedVals
FOR OrderedVals IN ([1],[2],[3],[4],[5],[6])
答案 2 :(得分:1)
这类似于Larnu的回答,但它应该具有更好的性能,因为它避免了整个表的聚集。此外,它返回与原始数据相同的行,而不会引入伪造的def save(self,*args,**kwargs):
total_records = About.objects.count()
if total_records >= 2:
raise DbLimitException({"message": "Db limit reached please delete to add more data"})
else:
super().save(*args,**kwargs)
。
您可以在id
内进行汇总:
CROSS APPLY
答案 3 :(得分:0)
您可以在不使用数据透视的情况下使用此代码
DECLARE @T
TABLE(n1 INT, n2 INT, n3 INT, n4 INT, n5 INT, n6 INT,Type VARCHAR(10))
INSERT INTO @T(n1, n2, n3, n4, n5, n6, Type)
SELECT 6 , 15 , 10 , 11 , 22 , 25 , 'C1'
UNION SELECT 2 , 5 , 1 , 20 , 21 , 30 , 'C1'
UNION SELECT 15 , 25 , 18 , 4 , 12 , 38 , 'C2'
UNION SELECT 11 , 1 , 4 , 9 , 24 , 31 , 'C2'
SELECT SUM(CASE WHEN ord=1 THEN n ELSE 0 END) AS Nr1,
SUM(CASE WHEN ord=2 THEN n ELSE 0 END) AS Nr2,
SUM(CASE WHEN ord=3 THEN n ELSE 0 END) AS Nr3,
SUM(CASE WHEN ord=4 THEN n ELSE 0 END) AS Nr4,
SUM(CASE WHEN ord=5 THEN n ELSE 0 END) AS Nr5,
SUM(CASE WHEN ord=6 THEN n ELSE 0 END) AS Nr6,
Type
FROM (SELECT *,ROW_NUMBER()OVER(ORDER by Type) as unq
FROM @T
)AS IndexedT
CROSS APPLY(SELECT n , ROW_NUMBER()OVER(ORDER by n) as ord
FROM ( SELECT n1 as n
UNION SELECT n2
UNION SELECT n3
UNION SELECT n4
UNION SELECT n5
UNION SELECT n6
)as X
) AS PivotItem
GROUP BY unq,Type