我有这样的数据
d b c
a d
c b
a b
c a
c a d
c
如果你分析,你会发现每个元素的外观如下
a:4 b:3 c:5 d:2
根据外观,我的排序元素将是 C,A,B,d
,最终输出应为
c b d
a d
c b
a b
c a
c a d
C
有任何线索,我们如何使用sql查询实现这一目标?
答案 0 :(得分:0)
除非有另一列指示输入行的顺序,否则将无法保证输出行以相同的顺序返回。我在这里假设通过三列值对它们进行排序,以便结果是确定性的。
可能可以将此代码压缩为更少的步骤,但可以合理地清楚地显示这些步骤。
请注意,对于大型数据集,将其中一些步骤划分为创建临时表或工作表的SELECT INTO
操作可能更有效。
DECLARE @t TABLE
(col1 CHAR(1)
,col2 CHAR(1)
,col3 CHAR(1)
)
INSERT @t
SELECT 'd','b','c'
UNION SELECT 'a','d',NULL
UNION SELECT 'c','b',NULL
UNION SELECT 'a','b',NULL
UNION SELECT 'c','a',NULL
UNION SELECT 'c','a','d'
UNION SELECT 'c',NULL,NULL
;WITH freqCTE
AS
(
SELECT col1 FROM @t WHERE col1 IS NOT NULL
UNION ALL
SELECT col2 FROM @t WHERE col2 IS NOT NULL
UNION ALL
SELECT col3 FROM @t WHERE col3 IS NOT NULL
)
,grpCTE
AS
(
SELECT col1 AS val
,COUNT(1) AS cnt
FROM freqCTE
GROUP BY col1
)
,rowNCTE
AS
(
SELECT *
,ROW_NUMBER() OVER (ORDER BY col1
,col2
,col3
) AS rowN
FROM @t
)
,buildCTE
AS
(
SELECT rowN
,val
,cnt
,ROW_NUMBER() OVER (PARTITION BY rowN
ORDER BY ISNULL(cnt,-1) DESC
,ISNULL(val,'z')
) AS colOrd
FROM (
SELECT *
FROM rowNCTE AS t
JOIN grpCTE AS g1
ON g1.val = t.col1
UNION ALL
SELECT *
FROM rowNCTE AS t
LEFT JOIN grpCTE AS g2
ON g2.val = t.col2
UNION ALL
SELECT *
FROM rowNCTE AS t
LEFT JOIN grpCTE AS g3
ON g3.val = t.col3
) AS x
)
SELECT b1.val AS col1
,b2.val AS col2
,b3.val AS col3
FROM buildCTE AS b1
JOIN buildCTE AS b2
ON b2.rowN = b1.rowN
AND b2.colOrd = 2
JOIN buildCTE AS b3
ON b3.rowN = b1.rowN
AND b3.colOrd = 3
WHERE b1.colOrd = 1
ORDER BY b1.rowN