我有一张桌子:
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.但我不介意了解其他数据库的解决方案。
答案 0 :(得分:3)
如果我理解正确,您需要表格中表示的parameter
个id
个 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/