简体   繁体   English

SQL Server,如何获取多个不同的项目

[英]SQL server, how to get a number of distinct items

I am using SQL server,我正在使用 SQL 服务器,

  id          3     | 4    | 5 | 6
  items       1 2 3 | 2 3 5| 6 | 1 2 5
    -------------------------
  # of items      3 | 4    | 5 | 5

so, each id has items (ex, 3 has 3 items - 1,2,3) and for each item, I'd like to get the number of distinct items accrued.所以,每个 id 都有项目(例如,3 有 3 个项目 - 1,2,3),对于每个项目,我想获得不同项目的数量。

so, 3 has 3 distinct items - 1, 2, 3所以, 3 有 3 个不同的项目 - 1, 2, 3
4 has 4 distinct items - 1, 2, 3, 5 4 有 4 个不同的项目 - 1, 2, 3, 5
5 has 5 distinc items - 1, 2, 3, 5, 6 5 有 5 个不同的项目 - 1, 2, 3, 5, 6
6 has 5 distinct items - 1, 2, 3, 5, 6 6 有 5 个不同的项目 - 1, 2, 3, 5, 6

I can do this by running, 1 through 2, 1 though 3, 1 through 5 and 1 through 6 by doing count(distinct items) But I want to automate this process and get the same results in one run.我可以通过运行 1 到 2、1 到 3、1 到 5 和 1 到 6 来执行计数(不同项目)但我想自动化这个过程并在一次运行中获得相同的结果。

The idea is to create a temp table and put an item in it while checking if the item is already in the temp table and print number of distinct items for each id.这个想法是创建一个临时表并将一个项目放入其中,同时检查该项目是否已经在临时表中并为每个 id 打印不同项目的数量。

CREATE TABLE TEST
(
    id int, items int
)

INSERT INTO TEST
VALUES
(3, 1),
(3, 2),
(3, 3),
(4, 2),
(4, 3),
(4, 5),
(5, 6),
(6, 1),
(6, 2),
(6, 5)

SELECT B.id, COUNT(DISTINCT(A.ITEMS)) AS itemCount
FROM TEST A
INNER JOIN TEST B ON A.id <= B.id
GROUP BY B.ID

DROP TABLE TEST

Output: 
id  itemCount
3   3
4   4
5   5
6   5

Assuming your data in below format:假设您的数据采用以下格式:

Declare @table table
(
id int,
items varchar(10)
)

insert into @table values (3, '1 2 3');
insert into @table values (4, '2 3 5');
insert into @table values (5, '6');
insert into @table values (6, '1 2 5');

with cte as
(
Select id, b.Item
from @table a
cross apply [dbo].[Split] (items, ' ') b
)

Select y.id, count(distinct(x.Item)) AS [# of items]
from cte x
join cte y on x.id <= y.id
group by y.id

Use the table valued function [dbo].[Split] from LINK .使用来自LINK的表值函数[dbo].[Split]

You can as the below:你可以如下:

DECLARE @Tbl TABLE (Id VARCHAR(10), Column3 VARCHAR(100), Column4 VARCHAR(100), Column5 VARCHAR(100), Column6 VARCHAR(100))
INSERT @Tbl
VALUES 
('items', '1 2 3', '2 3 5', '6', '1 2 5')   

;WITH CTE1
AS
(
    SELECT T.Id, T.Column3 AS ColumnId, CAST('<X>' + REPLACE(T.Column3,' ','</X><X>') + '</X>' as XML) AS FilterColumn FROM  @Tbl T UNION ALL
    SELECT T.Id, T.Column4 AS ColumnId, CAST('<X>' + REPLACE(T.Column4,' ','</X><X>') + '</X>' as XML) AS FilterColumn FROM  @Tbl T UNION ALL
    SELECT T.Id, T.Column5 AS ColumnId, CAST('<X>' + REPLACE(T.Column5,' ','</X><X>') + '</X>' as XML) AS FilterColumn FROM  @Tbl T UNION ALL
    SELECT T.Id, T.Column6 AS ColumnId, CAST('<X>' + REPLACE(T.Column6,' ','</X><X>') + '</X>' as XML) AS FilterColumn FROM  @Tbl T 
), CTE2
AS 
(
    SELECT 
        A.*,
        B.SplitData
    FROM
        CTE1 A CROSS APPLY
        (SELECT fdata.D.value('.','varchar(50)') AS SplitData FROM A.FilterColumn.nodes('X') as fdata(D)) B
)

SELECT
    T.Id ,
    (SELECT COUNT(DISTINCT C.SplitData) FROM CTE2 C WHERE C.Id = T.Id AND C.ColumnId IN (T.Column3)) Column3OfDistinct,
    (SELECT COUNT(DISTINCT C.SplitData) FROM CTE2 C WHERE C.Id = T.Id AND C.ColumnId IN (T.Column3, T.Column4)) Column4OfDistinct,
    (SELECT COUNT(DISTINCT C.SplitData) FROM CTE2 C WHERE C.Id = T.Id AND C.ColumnId IN (T.Column3, T.Column4, T.Column5)) Column5OfDistinct,
    (SELECT COUNT(DISTINCT C.SplitData) FROM CTE2 C WHERE C.Id = T.Id AND C.ColumnId IN (T.Column3, T.Column4, T.Column5, T.Column6)) Column6OfDistinct    
FROM
    @Tbl T

Result:结果:

Id         Column3OfDistinct Column4OfDistinct Column5OfDistinct Column6OfDistinct
---------- ----------------- ----------------- ----------------- -----------------
items      3                 4                 5                 5

This should help you:这应该可以帮助您:

    select
        id,
        count(items)
    from table_name
    group by id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM