选择一个表的所有记录,其中包含另一个具有特定ID的两个记录

时间:2020-07-03 13:49:01

标签: sql sql-server join left-join

我有两个1:m关系表。需要选择ID为1和2的“动作”表中哪些记录同时包含这两个记录

People
+----+------+--------------+
| id | name | phone_number |
+----+------+--------------+
| 1  | John | 111111111111 |
+----+------+--------------+
| 3  | Jane | 222222222222 |
+----+------+--------------+
| 4  | Jack | 333333333333 |
+----+------+--------------+

Action
+----+------+------------+
| id | PplId| ActionId   |
+----+------+------------+
| 1  |   1  |      1     |
+----+------+------------+
| 2  |   1  |      2     |
+----+------+------------+
| 3  |   2  |      1     |
+----+------+------------+
| 4  |   4  |      2     |
+----+------+------------+

Output
+----+------+--------------+----------
|PplId| name | Phone       |ActionId |
+-----+------+-------------+----+-----
| 1   | John | 111111111111|   1     |
+-----+------+-------------+----+-----
| 1   | John | 111111111111|   2     |
+-----+------+-------------+----+-----

   

同时具有动作ID 1和动作ID 2(具有动作记录)的人员的返回记录。

3 个答案:

答案 0 :(得分:1)

窗口函数是一种方法。假设某人的操作不重复:

select pa.*
from (select p.*, a.action, count(*) over (partition by p.id) as num_actions
      from people p join
           action a
           on p.id = a.pplid
      where a.action in (1, 2)
     ) pa
where num_actions = 2;

我认为,获得两行包含操作详细信息似乎是多余的-您已经知道操作了。如果您只想要人们,那么exists就会浮现在脑海:

select p.*
from people p
where exists (select 1 from actions where a.pplid = p.id and a.action = 1) and
      exists (select 1 from actions where a.pplid = p.id and a.action = 2);

使用正确的索引(actions(pplid, action)),我希望两个existsgroup by快。

答案 1 :(得分:0)

在下面的查询中尝试使用子查询并加入

select a.Pplid, name, phone, actionid from (
select a.pplid as Pplid, name, phone_number as phone
from People P
join Action A on a.pplid= p.id
group by a.pplid, name, phone_number
having count(*)>1 )P
join Action A on a.Pplid= p.Pplid

答案 2 :(得分:0)

尝试这样的事情

IF OBJECT_ID('tempdb..#People') IS NOT NULL DROP TABLE #People
CREATE TABLE #People (id INT, name VARCHAR(255), phone_number VARCHAR(50))
INSERT #People
SELECT 1, 'John', '111111111111' UNION ALL
SELECT 3, 'Jane', '222222222222' UNION ALL
SELECT 4, 'Jack', '333333333333' 
IF OBJECT_ID('tempdb..#Action') IS NOT NULL DROP TABLE #Action
CREATE TABLE #Action (id INT, PplId INT, ActionId INT)
INSERT #Action
SELECT 1, 1, 1 UNION ALL
SELECT 2, 1, 2 UNION ALL
SELECT 3, 2, 1 UNION ALL
SELECT 4, 4, 2
GO

SELECT      p.ID                AS PplId
            , p.name
            , p.phone_number    AS Phone
            , a.ActionId
FROM        #People p
JOIN        #Action a
ON          p.ID = a.PplId
WHERE       p.ID IN (   SELECT      PplId 
                        FROM        #Action
                        WHERE       ActionId IN (1, 2) 
                        GROUP BY    PplId
                        HAVING      COUNT(*) = 2    )
            AND a.ActionId IN (1, 2)
GO
相关问题