我有一个文本列,其数值用分号分隔。我试图弄清楚如何获得出现在同一行中的最频繁的一对值。我在Python Finding the most frequent occurrences of pairs in a list of lists中找到了一个非常类似的问题的解决方案,但是我不知道如何使用SQL重写它。在下面的示例中,它返回2和3,因为该对在输入集中出现了3次。 :
Input rows Output
---------- -------
';1;2;3;5' | '2;3'
';2;3' | '1;2'
';3;4;5;1;2' | '1;3'
';1;5;2' | '1;5'
原始数据:
答案 0 :(得分:1)
您可以尝试以下方法。首先,使用OPENJSON()
,获取所有可能的组合。当OPENJSON
解析JSON数组时,JSON文本中元素的索引将作为键(从0开始)返回。然后,用DENSE_RANK()
计算最频繁的货币对。
输入:
CREATE TABLE #Items (
Id int,
ItemValues varchar(max)
)
INSERT INTO #Items
(Id, ItemValues)
VALUES
(1, '1;2;3;5'),
(2, '2;3'),
(3, '3;4;5;1;2'),
(4, '1;5;2')
声明:
;WITH combinationsCTE AS (
SELECT
CASE
WHEN s1.[value] <= s2.[value] THEN CONCAT(s1.[value], ';', s2.[value])
ELSE CONCAT(s2.[value], ';', s1.[value])
END AS PairValue
FROM #Items i
CROSS APPLY (SELECT [key], [value] FROM OPENJSON('["' + REPLACE(i.ItemValues,';','","') + '"]')) s1
CROSS APPLY (SELECT [key], [value] FROM OPENJSON('["' + REPLACE(i.ItemValues,';','","') + '"]')) s2
WHERE (s1.[key] < s2.[key])
), rankingCTE AS (
SELECT
PairValue,
DENSE_RANK() OVER (ORDER BY COUNT(PairValue) DESC) AS PairRank
FROM combinationsCTE
GROUP BY PairValue
)
SELECT PairValue
FROM rankingCTE
WHERE PairRank = 1
输出:
PairValue
1;2
1;5
2;3
2;5
答案 1 :(得分:0)
首先具有拆分功能
CREATE FUNCTION Splitfn(@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
第二步以单个字符串获取所有行
Declare @val Varchar(MAX);
Select @val = COALESCE(@val + '; ' + YourColumn, YourColumn)
From YourTable
第三步
SELECT TOP 1 items, count(*)
FROM dbo.Splitfn(@Val, ';')
WHERE LTRIM(RTRIM(items)) <> ''
GROUP BY items
ORDER BY Count(*) DESC