我正在尝试从SQL Server 2008中的查询中获取一些记录。
表的存储方式就像这样
P_Id Activity_Id
-----------------------
1234 53
1234 510
4567 65
4567 510
3456 53
3456 540
5678 53
5678 510
现在我需要得到的是P_Id预订的活动53& 510或65& 510
如果我这样做,它就没有给我记录
SELECT P_Id FROM ActivitiesPerPerson WHERE Activity_Id = 53 AND Activity_Id = 510
如果我这样做
SELECT P_Id FROM ActivitiesPerPerson WHERE Activity_Id IN (53, 65, 510)
它给了我一些结果,但它给了我的人预订活动53只与其他人一起。
我需要获得预订53& 510一起和预订65& 510在一起。如果可能,所有结果都相同。
我有一个sql小提琴 http://sqlfiddle.com/#!3/b4c11/2
提前致谢
答案 0 :(得分:2)
将您的问题解释为“找到所有在某一组中完成所有活动的人”,您可以这样做:
SELECT P_Id, COUNT(*)
FROM ActivitiesPerPerson
WHERE Activity_Id IN (50, 510, 800)
GROUP BY P_Id
HAVING COUNT(*) = 3;
(针对您的小提琴数据进行了调整,并假设ActivitiesPerPerson
每(PersonId, ActivityID)
对是唯一的 - 即同一个人不能多次执行相同的活动。您还需要每次更改条件数时调整count = x
。
如果你需要排除同一(person, activity)
组合重复的可能性,给出误报,请将它们区分开来:
SELECT P_Id, COUNT(*)
FROM
(
SELECT DISTINCT P_Id, Activity_ID
FROM ActivitiesPerPerson
WHERE Activity_Id IN (50, 510, 800)
) X
GROUP BY P_Id
HAVING COUNT(*) = 3;
Activities
条件集可以表示为表变量或表值参数 - 这有助于保持这种方法的可维护性(特别是count = x变化)。 Another Fiddle
答案 1 :(得分:1)
这有点可怕但有效。从你的小提琴中取出的数字。
SELECT *
FROM
(SELECT P_Id
FROM ActivitiesPerPerson
WHERE Activity_Id = 510) AS x INNER JOIN
(SELECT P_Id
FROM ActivitiesPerPerson
WHERE Activity_Id = 50) AS y ON x.P_Id = y.P_Id INNER JOIN
(SELECT P_Id
FROM ActivitiesPerPerson
WHERE Activity_Id = 800) AS z ON x.P_Id = z.P_Id
答案 2 :(得分:1)
您将扫描一次表并按P_Id分组。完成后,你需要一个聚合来告诉你,那个P_Id有一个Activity_Id x。你可以简单地总结一个case子句。然后只选择符合您条件的P_Id:
SELECT P_Id
FROM ActivitiesPerPerson
WHERE Activity_Id IN (53, 65, 510)
GROUP BY p_Id
HAVING
(
SUM( CASE WHEN Activity_Id = 53 THEN 1 ELSE 0 END ) > 0
AND
SUM( CASE WHEN Activity_Id = 510 THEN 1 ELSE 0 END ) > 0
)
OR
(
SUM( CASE WHEN Activity_Id = 65 THEN 1 ELSE 0 END ) > 0
AND
SUM( CASE WHEN Activity_Id = 510 THEN 1 ELSE 0 END ) > 0
);
答案 3 :(得分:0)
如果您总是需要两个活动的交集,您可以执行以下操作。我将它包装在一个表函数中,该函数将2个活动ID作为输入变量。
Declare @Act1 Int
Declare @Act2 Int
Set @Act1 = 50
Set @Act2 = 510
SELECT A1.P_Id
FROM
ActivitiesPerPerson A1
INNER JOIN
ActivitiesPerPerson A2
ON A1.P_Id = A2.P_Id
WHERE A1.Activity_Id = @Act1
AND A2.Activity_Id = @Act2