2017-02-28 28 views
0

嗨,我需要一个复杂的查询 我的表结构逗号有相同值的列获取数分隔格式的Sql

attribute_id value entity_id 
188   48,51,94  1 
188   43,22  2 
188   43,22  3 
188   43,22  6 
190   33,11  10 
190   90,61  12 
190   90,61  15 

我需要的价值像

attribute_id value count 
188   48   2 
188   43   3 
188   51   1 
188   94   1 
188   22   2 
190   33   1 
190   11   1 
190   90   2 
190   61   2 

我有计搜索了很多谷歌有这样的事情,但不幸的是我没有得到任何成功。请建议我如何实现这一点。

+0

是已知的,固定的可能值的范围,或可能有任何数量的值出现的? –

+0

不,他们不是固定的,我只能在查询中传递attribute_id值。请建议。 –

+0

千万不要将数据存储为逗号分隔的项目!这只会导致你很多问题。 – jarlh

回答

0

我对这样的事情使用UDF。如果这能为你工作:

CREATE FUNCTION [dbo].[UDF_StringDelimiter] 
/********************************************************* 
** Takes Parameter "LIST" and transforms it for use ** 
** to select individual values or ranges of values. ** 
**              ** 
** EX: 'This,is,a,test' = 'This' 'Is' 'A' 'Test'  ** 
*********************************************************/ 
    (
      @LIST    VARCHAR(8000) 
     ,@DELIMITER  VARCHAR(255) 
    ) 

RETURNS @TABLE TABLE 
    ( 
     [RowID] INT IDENTITY 
     ,[Value] VARCHAR(255) 
    ) 
WITH SCHEMABINDING 
AS 
BEGIN 
    DECLARE 
     @LISTLENGTH AS SMALLINT 
     ,@LISTCURSOR AS SMALLINT 
     ,@VALUE AS VARCHAR(255) 
    ; 
    SELECT 
     @LISTLENGTH = LEN(@LIST) - LEN(REPLACE(@LIST,@DELIMITER,'')) + 1 
     ,@LISTCURSOR = 1 
     ,@VALUE = '' 
    ; 
    WHILE @LISTCURSOR <= @LISTLENGTH 
    BEGIN 

     INSERT INTO @TABLE (Value) 
     SELECT 
      CASE 
       WHEN @LISTCURSOR < @LISTLENGTH 
        THEN SUBSTRING(@LIST,1,PATINDEX('%' + @DELIMITER + '%',@LIST) - 1) 
       ELSE SUBSTRING(@LIST,1,LEN(@LIST)) 
      END 
     ; 
     SET @LIST = STUFF(@LIST,1,PATINDEX('%' + @DELIMITER + '%',@LIST),'') 
     ;  
     SET @LISTCURSOR = @LISTCURSOR + 1 
     ; 
    END 
    ; 
    RETURN 
    ; 
END 
; 

的UDF有两个参数:要分割的字符串,并且分隔符的分裂。多年来,我一直在使用它来处理各种不同的事情,因为有时候你需要用逗号分隔,有时候用空格,有时用整个字符串。

一旦你的UDF,你可以这样做:

DECLARE @TABLE TABLE 
(
    Attribute_ID INT 
    ,Value VARCHAR(55) 
    ,Entity_ID INT 
); 

INSERT INTO @TABLE VALUES (188, '48,51,94', 1); 
INSERT INTO @TABLE VALUES (188, '43,22', 2); 
INSERT INTO @TABLE VALUES (188, '43,22', 3); 
INSERT INTO @TABLE VALUES (188, '43,22', 6); 
INSERT INTO @TABLE VALUES (190, '33,11', 10); 
INSERT INTO @TABLE VALUES (190, '90,61', 12); 
INSERT INTO @TABLE VALUES (190, '90,61', 15); 

SELECT 
    T1.Attribute_ID 
    ,T2.Value 
    ,COUNT(T2.Value) AS Counter 
FROM @TABLE T1 
CROSS APPLY dbo.UDF_StringDelimiter(T1.Value,',') T2 
GROUP BY T1.Attribute_ID,T2.Value 
ORDER BY T1.Attribute_ID ASC, Counter DESC 
; 

我做了一个ORDER BY Attribute_ID上升,然后下降计数器,让你得到每个Attribute_ID最常见的重复值第一。当然,你可以改变它。

返回此:

Attribute_ID  Value  Counter 
----------------------------------- 
188    43   3 
188    22   3 
188    94   1 
188    48   1 
188    51   1 
190    61   2 
190    90   2 
190    11   1 
190    33   1