Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL查询:查找最频繁的值对_Sql_Sql Server_Tsql - Fatal编程技术网

T-SQL查询:查找最频繁的值对

T-SQL查询:查找最频繁的值对,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个文本列,其中的数值用分号分隔。我试图找出如何获得同一行中出现频率最高的一对值。我在Python中找到了一个非常类似的问题的解决方案,但我不知道如何在下面的示例中使用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'

我有一个文本列,其中的数值用分号分隔。我试图找出如何获得同一行中出现频率最高的一对值。我在Python中找到了一个非常类似的问题的解决方案,但我不知道如何在下面的示例中使用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'
原始数据:


首先有一个拆分函数

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
第三步

SELECT TOP 1 items, count(*)
FROM dbo.Splitfn(@Val, ';')
WHERE LTRIM(RTRIM(items)) <> ''
GROUP BY items
ORDER BY Count(*) DESC

您可以尝试以下方法。首先,使用OPENJSON获取所有可能的组合。当OPENJSON解析JSON数组时,JSON文本中元素的索引将作为基于0的键返回。然后,计算具有密集_秩的最频繁对

输入:

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

请以文本格式发布数据,而不是图像。此外,你还需要解释940和10662是怎样的预期结果。阅读,你会看到很多原因,为什么这个问题的答案绝对是肯定的!你有一个坏的数据模型,这就是为什么很难使用它。如果要规范化数据库,此任务将非常简单。您的SQL Server版本是什么Developers@AdamStawarek为什么1;2, 1;5和2;5不在输出中?分别为2;3和3;2相同?这可能是在SQL中拆分字符串最糟糕的方法。如果使用2016版或更高版本,最好使用内置字符串分割。对于较低版本,请阅读Aaron Bertrand的《这将返回最频繁的值》,但我的目的是获取最频繁的值对,因此对于每行中的每一组值,我需要找到所有值的组合,并返回在整个集合中最常见的值谢谢,这就是我所需要的
;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