SQL Count由参数定义的唯一对象

时间:2010-06-12 00:09:58

标签: sql sql-server sql-server-2000

我有一张桌子:

id | parameter
 1 | A
 1 | B
 2 | A
 3 | A
 3 | B

表示使用以下值定义的对象:

 1 -> A,B
 2 -> A
 3 -> A,B

我想使用SQL查询计算具有不同参数的对象的数量,因此在这种情况下,它将是2个唯一对象,因为1和3具有相同的参数。

参数数量没有限制,可以有0或任何其他数字。

数据库是Microsoft SQL Server 2000.但我不介意了解其他数据库的解决方案。

5 个答案:

答案 0 :(得分:3)

如果我理解正确,您需要表格中表示的parameterid SELECT parameter_set, COUNT(*) AS entity_count FROM ( -- Here we "flatten" the different parameter combinations per id SELECT id, GROUP_CONCAT(parameter ORDER BY parameter) AS parameter_set FROM tbl GROUP BY id ) d GROUP BY parameter_set; 的不同组合的数量,可能包含展示每个 parameter_set | entity_count ---------------+-------------- A,B | 2 -- two entities have params A, B A | 1 -- one entity has param A 的实体数量不同的组合。

我不能代表SQL Server,但在MySQL下你可以这样做:

SELECT COUNT(DISTINCT parameter_set FROM (... flattening query ...)) d

会给你这个:

{{1}}

和{{1}}将为您提供不同参数集的数量。

答案 1 :(得分:2)

好的,这是我的尝试。有可能以不需要访问同一个表的方式实现这个逻辑,但我现在想不到它。

这里的逻辑是首先消除重复的对象,然后计算剩余的ID。 NOT IN子查询表示具有较小ID的匹配对象的对象。子查询连接两个对象t1和t2的参数,然后计算每个t1 / t2对匹配的参数数量。如果匹配参数的数量与t1和t2中的参数数量相同,那么t2和t1是匹配的,我们应该从结果集中排除t1。

DECLARE @tab TABLE (ID int, parameter varchar(2));

INSERT INTO @tab
SELECT 1, 'A' UNION ALL
SELECT 1, 'B' UNION ALL
SELECT 2, 'A' UNION ALL
SELECT 3, 'A' UNION ALL
SELECT 3, 'B' UNION ALL
SELECT 4, 'A' UNION ALL
SELECT 5, 'C' UNION ALL
SELECT 5, 'D';

SELECT
    COUNT(DISTINCT t.ID) AS num_groups
FROM
    @tab AS t
WHERE
    t.ID NOT IN
        (SELECT
             t1.ID AS ID1
         FROM
                 @tab AS t1
             INNER JOIN
                 @tab AS t2
             ON
                 t1.ID > t2.ID AND
                 t1.parameter = t2.parameter
         GROUP BY
             t1.ID,
             t2.ID
         HAVING
             COUNT(*) = (SELECT COUNT(*) FROM @tab AS dupe WHERE dupe.ID = t1.ID) AND
             COUNT(*) = (SELECT COUNT(*) FROM @tab AS dupe WHERE dupe.ID = t2.ID)
        );

SQL Server 2008 R2上的结果:

num_groups
3

对于具有0个参数的对象,它取决于它们的存储方式,但一般来说,如果有任何具有0个参数的对象,您只需要在上面的答案中添加一个。

答案 2 :(得分:1)

在SQL Server 2000中没有万无一失的方法在指定条件下执行此操作,但以下内容适用于大多数情况,如果不起作用,它将发出警告。

给出表格,“ tbl ”:

ID  Parameter
 1      A
 1      B
 2      A
 3      A
 3      B
 4      A
 4      NULL
 5      C
 5      D
 6      NULL


创建此功能:

CREATE FUNCTION MakeParameterListFor_tblID (@ID INT)
RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE
        @ParameterList  VARCHAR(8000),
        @ListLen        INT
    SET
        @ParameterList  = ''

    SELECT
        @ParameterList  = @ParameterList + COALESCE (Parameter, '*null*') + ', '
    FROM
        tbl
    WHERE
        ID  = @ID
    ORDER BY
        Parameter


    SET @ListLen        = LEN (@ParameterList)
    IF  @ListLen > 7800 -- 7800 is a SWAG.
        SET @ParameterList  = '*Caution: overflow!*' + @ParameterList
    ELSE
        SET @ParameterList  = LEFT (@ParameterList, @ListLen-1) -- Kill trailing comma.

    RETURN @ParameterList
END
GO


然后这个查询:

SELECT
    COUNT (ID)   AS NumIDs,
    NumParams,
    ParamList
FROM
    (
        SELECT
            ID,
            COUNT (Parameter)                   AS NumParams,
            dbo.MakeParameterListFor_tblID (ID) AS ParamList
        FROM
             tbl
        GROUP BY
            ID
    ) AS ParamsByID
GROUP BY
    ParamsByID.ParamList,
    ParamsByID.NumParams
ORDER BY
    NumIDs      DESC,
    NumParams   DESC,
    ParamList   ASC


会给你所要求的。
结果:

NumIDs  NumParams   ParamList
  2         2         A, B
  1         2         C, D
  1         1         *null*, A
  1         1         A
  1         0         *null*

答案 3 :(得分:0)

您可以使用having子句过滤两个唯一参数:

select  count(*)
from    YourTable
group by
        id
having  count(distinct parameter) > 1

答案 4 :(得分:0)

我使用Cheran S提供的链接解决了问题(因为Microsoft SQL Server仍然没有GROUP_CONCAT()函数) http://dataeducation.com/rowset-string-concatenation-which-method-is-best/