0

だから、私はユーザーと活動を含むテーブルを持っています

users
id | activities
1 | "-2-3-4-"
2 | "-3-4-"
3 | "-1-2-3-4-"

activities
id | title
1 | running
2 | walking 
3 | climbing
4 | singing

ID 3のユーザーが、少なくとも2つの同じアクティビティを持つユーザーを見つけようとしています。私がやろうとしたことはこれです

SELECT u.id FROM users u 
WHERE ( SELECT COUNT(a.id) FROM activities a 
        WHERE a.id IN(TRIM( ',' FROM REPLACE( u.activities, '-', ',' ) )) 
AND a.id IN(1,2,3) ) >= 2

何か案は?

4

2 に答える 2

1

念のため、user_id と activity_id を含む 3 番目のテーブルを作成します。

これは決して適切な解決策ではありません。

すべてのアクティビティを users テーブルに一列に格納するのではなく、ユーザーとアクティビティを関連付けるテーブルが必要です。

于 2012-05-10T10:18:10.377 に答える
0

最初に、user.activities 文字列を受け取り、文字列をアクティビティの int ID に分割する関数を次のように作成できます。

create FUNCTION dbo.SplitStringToIds (@acts nvarchar(MAX))
RETURNS @acivityids TABLE (Id int)

AS
BEGIN

DECLARE @stringToInsert nvarchar (max) 
set @stringToInsert=''
DECLARE @intToInsert int 
set @intToInsert=0
DECLARE @stidx int 
set @stidx=0
DECLARE @endidx int 
set @endidx=0

WHILE LEN(@acts) > 3
BEGIN
    set @stidx=CHARINDEX('-', @acts, 1)
    set @acts=substring(@acts,@stidx+1,len(@acts))
    set @endidx=CHARINDEX('-', @acts, 1)-1

    set @stringToInsert=substring(@acts,1,@endidx)
    set @intToInsert=cast(@stringToInsert as int)
    INSERT INTO @acivityids
    VALUES
    (
    @intToInsert
    )

    END


-- Return the result of the function
RETURN 

エンドゴー

次に、このようなことを試して、id = 3のユーザーと2つ以上の同じアクティビティを持つユーザーを取得できます

select u.id,count(u.id) as ActivitiesCounter from users as u
cross apply SplitStringToIds(u.activities) as v
where v.id in (select v.id from users as u
cross apply SplitStringToIds(u.activities) as v
where u.id=3)
group by u.id having count(u.id)>=2

しかし、テーブル間のリレーションシップを格納するこの方法では問題が発生するだけだと思います。可能であれば、リレーションシップ テーブルを追加することをお勧めします。

于 2012-05-10T13:05:51.337 に答える