需要一些SQL帮助 - 获得共同的项目数量

时间:2015-06-09 13:52:22

标签: sql sql-server

想象一下,我有一个像这样的表

UserID      Name      Hobbies
00001       Jim       Baseball, Hockey, Astonomy
00002       Jack      Baseball, Football, Video Games
00003       Jill      Astronomy, Shopping, Soccer
00004       Jane      Hockey, Astronomy, Video Games
00005       Jacob     Football, Basketball, Video Games

现在,我想做的就是得到一些共同的爱好。所以,假设我将00001插入文本框或查询字符串或其他任何内容。我希望看到类似的东西:

Name    Hobbies
Jack    You have (1) hobby in common
Jill    You have (1) hobby in common
Jane    You have (2) hobbies in common
Jacob   You have (0) hobbies in common

我该如何编写代码呢?我很难过。我认为它与字符串匹配有关,但我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

首选是修复数据结构。以逗号分隔的列表是坏的,坏的,坏的。一个单独的桌子,每人和每个爱好存储一排是好的,好的,好的。

如果你被别人的坏决定困住,那就有一点追索权。首先是谷歌“sql server split”并获得你最喜欢的字符串拆分功能。

然后,你可以这样做:

with t as (
      select t.*, s.val as hobby
      from table t cross apply
           dbo.split(t.Hobbies, ', ') as s(val) -- Note, some `split()` implementations also have a `pos` value
     )
select t.userName, count(tuser.userId) as NumInCommon
from t left join
     t tuser
     on t.hobby = tuser.hobby and tuser.userId = '00001'
group by t.userId, t.userName;

除非你真的想要,否则不值得在SQL中构造完整的句子。主要使用SQL来获取所需的数据。 (SQL中的格式化有时很有用,但对于应用程序代码来说更是如此。)

答案 1 :(得分:0)

create table #temp_hobbies
(hobby_id int
,hobby varchar(50))

insert into #temp_hobbies values
(1, 'football')
,(2,'baseball')


create table #temp_people
(user_ids int,
name varchar(50),
hobby_ids int)
insert into #temp_people values
(01,'Adam',1)
,(01,'Adam',2)
,(02,'Dave',1)
,(03,'Matt',2)

select count(distinct hobby) , count(distinct name)
from #temp_hobbies a
inner join #temp_people b on a.hobby_id = b.hobby_ids 

您的解决方案的一部分,您现在需要添加查询,该查询将为每个用户的计算列提供与其他用户相比的业余爱好。 但是其他用户尝试将业余爱好分成一个单独的表并使用int来进行连接。如果您需要为数千条记录执行此操作,则SQL Server处理int的速度比varchar的esp更快。

答案 2 :(得分:0)

首先请正常化您的数据。你可以看到每一行都有很多重复的爱好,而且搜索和维护也会很乏味。

您可以将所有USERS数据放在一个表格中,如下所示:

CREATE TABLE USERS ( UserID , NAME ); --> USERID being PRIMARY KEY

您可以将所有HOBBIES放在另一张表中,如下所示:

CREATE TABLE HOBBIES ( HOBBYID, HOBBYNAME); --> HOBBYID being PRIMARY KEY

您可以使用另一个表格将USERS与HOBBIES映射如下:

CREATE USERS_HOBBIES( USERID , HOBBYID ); 

如上所述对表进行标准化后,您可以通过查询得到所需的结果:

SELECT u.NAME , count(*) AS Hobbies FROM USERS u INNER JOIN
USERS_HOBBIES uh ON u.UserID  = uh.USERID INNER JOIN HOBBIES h ON
uh.HOBBYID = h.HOBBYID WHERE h.HOBBYID IN (
  (SELECT a.HOBBYID as HOBBYID FROM 
    (SELECT DISTINCT(HOBBYID) as HOBBYID FROM USERS_HOBBIES WHERE 
     USERID   = '00001' ) a INNER JOIN 
    (SELECT DISTINCT(HOBBYID) as HOBBYID FROM USERS_HOBBIES WHERE 
     USERID <> '00001' ) b ON a.HOBBYID = b.HOBBYID) ) 
 AND u.USERID = '00001'  GROUP BY u.NAME

P.S:以上查询语法在ORACLE