Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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
如何在mssql中按逗号分隔的列进行分组?_Sql_Sql Server - Fatal编程技术网

如何在mssql中按逗号分隔的列进行分组?

如何在mssql中按逗号分隔的列进行分组?,sql,sql-server,Sql,Sql Server,我有两张桌子 T1user Id Name CourseIds 1 Joel 1,2,3 2 Jeff 2,3,4 t2课程 CourseId CourseName 1 C# 2 Javascript 3 SQL 4 VB 我必须将这两个表连接起来,找出每个课程的数量——由一个用户组通过like学习 结果表 Courses Count C# 1 Javascript

我有两张桌子

T1user

Id  Name CourseIds

1   Joel  1,2,3 
2   Jeff  2,3,4
t2课程

CourseId CourseName

1         C# 
2         Javascript
3         SQL
4         VB
我必须将这两个表连接起来,找出每个课程的数量——由一个用户组通过like学习 结果表

Courses      Count

C#           1  
Javascript   2
SQL          2
VB           1 

我试过回答这个问题,但都没用。请帮助我。

首先,您应该修复数据结构。将ID列表存储在逗号分隔的列表中是不好的,原因有很多:

将数字存储为字符串是不好的。 在单个字段中存储多个值是错误的。 不能声明外键关系是不好的。 这样的列表不能利用索引。 连接表是一个更好的选择。 有时我们会被其他人的错误决定所困扰。在这种情况下,您可以随心所欲,但效率不高:

select c.coursename,
       (select count(*)
        from user u
        where ',' + u.courseids + ',' like '%,' + cast(c.id as varchar(255)) + ',%'
       ) as cnt
from courses c;

但实际上,与其将神秘的字符串操作放在一起,不如修复数据结构。

首先,您应该修复数据结构。将ID列表存储在逗号分隔的列表中是不好的,原因有很多:

With cte(courseids,si,ei)
As(
 Select courseids,
              1,
             charindex(',', courseids)
   From user

Union all

Select courseids,
            Cast( 1 +ei as int),
            Charindex(',',courseids,1+ei)
From cte 
Where ei >0
)
Select substring(courseids,si, case when ei>0 then ei- si else Len(courseids) end) as courseid into #t 
From cte;

Select count(1) as count, (select coursename from courses where courseid = t.courseid) as courses
From #t t
Group by courseid;
Drop table #t;
将数字存储为字符串是不好的。 在单个字段中存储多个值是错误的。 不能声明外键关系是不好的。 这样的列表不能利用索引。 连接表是一个更好的选择。 有时我们会被其他人的错误决定所困扰。在这种情况下,您可以随心所欲,但效率不高:

select c.coursename,
       (select count(*)
        from user u
        where ',' + u.courseids + ',' like '%,' + cast(c.id as varchar(255)) + ',%'
       ) as cnt
from courses c;

但实际上,与其将神秘的字符串操作放在一起,不如修复数据结构。

回答得晚,但您也可以这样继续

With cte(courseids,si,ei)
As(
 Select courseids,
              1,
             charindex(',', courseids)
   From user

Union all

Select courseids,
            Cast( 1 +ei as int),
            Charindex(',',courseids,1+ei)
From cte 
Where ei >0
)
Select substring(courseids,si, case when ei>0 then ei- si else Len(courseids) end) as courseid into #t 
From cte;

Select count(1) as count, (select coursename from courses where courseid = t.courseid) as courses
From #t t
Group by courseid;
Drop table #t;
     DECLARE @Table1 TABLE 
    (Id int, Name varchar(4), CourseIds varchar(5))
;

INSERT INTO @Table1
    (Id, Name, CourseIds)
VALUES
    (1, 'Joel', '1,2,3'),
    (2, 'Jeff', '2,3,4')
;

DECLARE @Table2 TABLE 
    (CourseId int, CourseName varchar(10))
;

INSERT INTO @Table2
    (CourseId, CourseName)
VALUES
    (1, 'C#'),
    (2, 'Javascript'),
    (3, 'SQL'),
    (4, 'VB')
;


declare @str varchar(max)

;with cte as (
SELECT    Id,Name,
     Split.a.value('.', 'VARCHAR(100)') AS Courseid  
 FROM  (SELECT  Id,Name, 
         CAST ('<M>' + REPLACE([CourseIds], ',', '</M><M>') + '</M>' AS XML) AS String  
     FROM  @Table1) AS A CROSS APPLY String.nodes ('/M') AS Split(a))

     select TT.CourseName,COUNT(C.Courseid) AS Courseid from cte C
     INNER JOIN @Table2 TT
     ON TT.CourseId = C.Courseid
     GROUP BY TT.CourseName

回答晚了,但你也可以这样继续

     DECLARE @Table1 TABLE 
    (Id int, Name varchar(4), CourseIds varchar(5))
;

INSERT INTO @Table1
    (Id, Name, CourseIds)
VALUES
    (1, 'Joel', '1,2,3'),
    (2, 'Jeff', '2,3,4')
;

DECLARE @Table2 TABLE 
    (CourseId int, CourseName varchar(10))
;

INSERT INTO @Table2
    (CourseId, CourseName)
VALUES
    (1, 'C#'),
    (2, 'Javascript'),
    (3, 'SQL'),
    (4, 'VB')
;


declare @str varchar(max)

;with cte as (
SELECT    Id,Name,
     Split.a.value('.', 'VARCHAR(100)') AS Courseid  
 FROM  (SELECT  Id,Name, 
         CAST ('<M>' + REPLACE([CourseIds], ',', '</M><M>') + '</M>' AS XML) AS String  
     FROM  @Table1) AS A CROSS APPLY String.nodes ('/M') AS Split(a))

     select TT.CourseName,COUNT(C.Courseid) AS Courseid from cte C
     INNER JOIN @Table2 TT
     ON TT.CourseId = C.Courseid
     GROUP BY TT.CourseName

可能首先要正确地重新规范化数据库,使每个项都位于自己的行中。然后,这个查询和许多其他查询将变得微不足道。可能首先要正确地重新规范化数据库,使每个项都位于自己的行中。我已经尝试过上面的方法,但是它给出了C-1、Javascript-2、SQL-1、VB-0。有什么我想改变的吗??不像我的结果集。@Prashanth。它在SQLFiddle中工作得很好:。我已经尝试了上面的方法,但它给出了C-1、Javascript-2、SQL-1、VB-0。有什么我想改变的吗??不像我的结果集。@Prashanth。它在SQL Fiddle中运行良好:。@prasanth您可以查看answer@prasanth你能看看答案吗