Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.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
Sql 在一列中按id从多行获取单个记录_Sql_Sql Server_Database_Resultset - Fatal编程技术网

Sql 在一列中按id从多行获取单个记录

Sql 在一列中按id从多行获取单个记录,sql,sql-server,database,resultset,Sql,Sql Server,Database,Resultset,我正在尝试从SQLServer2008中的查询中获取一些记录 桌子的摆放方式是这样的 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

我正在尝试从SQLServer2008中的查询中获取一些记录

桌子的摆放方式是这样的

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的个人id和一起预订65和510的个人id。如果可能的话,所有的结果都是一样的

我对这件事很感兴趣


提前感谢

将您的问题解释为“查找在给定集合中完成所有活动的所有人员”,您可以这样做:

SELECT P_Id, COUNT(*) 
  FROM ActivitiesPerPerson 
  WHERE Activity_Id IN (50, 510, 800)
  GROUP BY P_Id
  HAVING COUNT(*) = 3;
(针对您的FIDLE数据进行了调整,并假设每个
(PersonId,ActivityID)
对的
ActivitiesPerPerson
是唯一的,即同一个人不能多次执行相同的活动。每次更改条件数时,您还需要调整
计数=x

如果您需要排除相同的
(人员、活动)
组合出现误报的可能性,请按如下方式对其进行区分:

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;

活动
标准集可以表示为表变量或表值参数-这有助于该方法的可维护性(尤其是计数=x变化)。

将您的问题解释为“查找在给定集合中完成所有活动的所有人员”,您可以这样做:

SELECT P_Id, COUNT(*) 
  FROM ActivitiesPerPerson 
  WHERE Activity_Id IN (50, 510, 800)
  GROUP BY P_Id
  HAVING COUNT(*) = 3;
(针对您的FIDLE数据进行了调整,并假设每个
(PersonId,ActivityID)
对的
ActivitiesPerPerson
是唯一的,即同一个人不能多次执行相同的活动。每次更改条件数时,您还需要调整
计数=x

如果您需要排除相同的
(人员、活动)
组合出现误报的可能性,请按如下方式对其进行区分:

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变量)。

这有点可怕,但有效。数字取自您的小提琴

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

这有点可怕,但有效。数字取自你的小提琴

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

如果您总是只需要两个活动的交集,您可以执行如下操作:我将它包装在一个表函数中,该函数将两个活动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

如果您总是只需要两个活动的交集,您可以执行以下操作。我将它包装在一个表函数中,该函数将两个活动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

您需要扫描一次表并按p\U Id分组。完成此操作后,您需要一个聚合来告诉您该p\U Id是否有活动Id x。您只需使用case子句求和即可。然后只取与您的条件匹配的p\U 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
);

请参阅。

您将扫描该表一次,并按p\U Id分组。完成此操作后,您需要一个聚合来告诉您该p\U Id是否有活动Id x。您只需使用case子句求和即可。然后只取与您的条件匹配的p\U 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
);

请参阅。

我更喜欢你的答案而不是我的答案!这是完成问卷要求的正确方法。太好了。我想你误解了这个问题。但是,使用COUNT(DISTINCT Activity_Id)=3;AFAIK
COUNT(DISTINCT x)可以更容易地解决第一次查询中的重复问题
不能用于sql server中具有子句的
中?它不是“查找在给定集合中完成所有活动的所有人员”。我需要查找一起预订活动53和510或一起预订活动65和510的人员。我不需要只包含53而不包含510的案例。我不需要在结果中包含其他活动的人员。他们不会发出嘘声k 53、65和510加在一起。这只能是我上面提到的两个选项,因此IN不起作用。我更喜欢你的答案而不是我的答案!这是完成问卷要求的正确方法。太好了。我想你误解了这个问题。但是,通过计数(不同的活动Id)可以更容易地解决第一个查询中的重复问题=3;AFAIK
COUNT(不同的x)
不能用于sql server中具有
子句的
中?它不是“查找在给定集合中完成所有活动的所有人员”。我需要查找一起预订活动53和510或一起预订活动65和510的人员。我不需要只包含53而不包含510的案例。我不需要在结果中包含其他活动的人员。他们不会发出嘘声k 53、65和510一起。它只能是我上面提到的两个选项,所以IN不起作用。只需注意:WHERE子句实际上不需要,但可能会提高性能。另一个注意:您的示例(53和510)或(65和510)当然可以简化为510和(53或65)。谢谢!这正是我想要的!只是一个注释:WHERE子句实际上并不需要,但可能会提高性能。另一个注释:您的示例(53和510)或(65和510)当然可以简化为510和(53或65)。谢谢!这正是我想要的!