在SQL Query中与条件的一对多关系

时间:2017-03-16 14:38:34

标签: sql one-to-many

我有以下表格:

event_tbl

| event_id (PK) | event_date | event_location |
|---------------|------------|----------------|
| 1             | 01/01/2018 | Miami          |                
| 2             | 02/04/2018 | Tampa          |                    

performer_tbl

| performer_id (PK) | event_id (FK) | genre |
|-------------------|---------------|-------|
| 1                 | 1             |  A    |
| 2                 | 1             |  B    |
| 3                 | 2             |  A    |
| 4                 | 2             |  C    |

我想找到同时具有流派A和流派B的事件(应该只返回事件1),并且在编写查询时我迷失了方向。也许我只是没有足够的咖啡,但我能想到的只是做两个派生列,其中一个case语句通过event_id计算类型和组,然后将两者都过滤到> 0。它看起来并不优雅。

5 个答案:

答案 0 :(得分:1)

这适用于任何SQL数据库(至少在mysql,sql server,postgres或oracle中)

    select event_tbl.* FROM (
    select event_id
    from performer_tbl
    where genre = 'A'
    GROUP BY event_id) a_t
    INNER JOIN (select event_id
    from performer_tbl
    where genre = 'B'
    GROUP BY event_id) b_t
    ON a_t.event_id = b_t.event_id
    INNER JOIN event_tbl
    ON event_tbl.event_id = a_t.event_id

答案 1 :(得分:0)

如果您使用的是sql server,请查看以下内容:

  Select * From 
  event_tbl 
  where event_id 
  IN
  (
  select event_id 
   from performer_tbl as A
  where exists (select 1 
                from perfoermer_tbl as B 
                where B.event_id = A.event_id and B.genre = 'A')
        and
        exists (select 1 
                from perfoermer_tbl as B 
                where B.event_id = A.event_id and B.genre = 'B')
  )

答案 2 :(得分:0)

这应该可以胜任(在MySQL中,对于其他DBMS,语法可以轻松改变):

SELECT
e.event_id
FROM
event_tbl e
JOIN performer_tbl p USING(event_id)
GROUP BY e.event_id
HAVING SUM(IF(p.genre = 'A', 1, 0)) >= 1 AND SUM(IF(p.genre = 'B', 1, 0)) >= 1;

答案 3 :(得分:0)

这也可以使用左连接:(因为没有函数调用或子选择,所以它很快。而且,它在大多数SQL引擎中都可用。)

SELECT DISTINCT
   p1.event_id
   ,e.event_date
   ,e.event_location
FROM
   performer_tbl as p1
   inner join event_tbl as e on
      p1.event_id = e.event_id 
   left outer join performer_tbl as p2 on
      p1.event_id = p2.event_id 
      AND p2.genre = 'A'
   left outer join performer_tbl as p3 on
      p1.event_id = p3.event_id 
      AND p3.genre = 'B'
WHERE
    p2.genre IS NOT NULL
    AND p3.genre IS NOT NULL;

答案 4 :(得分:0)

如果我正确理解了你的需求,你可以试试这个:

Select *
  from event_tbl e
 where exists (select *
                 from performer_tbl p
                where p.event_id = e.event_id
                  and p.genre in ('A', 'B'))