简体   繁体   English

在SQL查询中具有条件的一对多关系

[英]In SQL Query a one-to-many relationship with condition

I have the following tables: 我有以下表格:

event_tbl event_tbl

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

performer_tbl performer_tbl

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

I want to find events that have both genre A and genre B (should just return event 1), and I'm lost on writing the query. 我想查找同时具有类型A和类型B的事件(应该返回事件1),并且在编写查询时迷失了方向。 Maybe I just haven't had enough coffee, but all I can come up with is doing two derived columns with a case statement that count either genre and group by the event_id, then filtering both to >0. 也许我只是没有喝咖啡,但是我所能想到的就是用一个case语句处理两个派生列,该语句对流派和event_id进行分组,然后都过滤为> 0。 It just doesn't seem very elegant. 看起来似乎不是很优雅。

This should work in any SQL database (at least in mysql, sql server, postgres or oracle) 这应该可以在任何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

if you are using sql server, check below: 如果您使用的是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')
  )

This should do the job (in MySQL, for other DBMS the syntax can be varied easily): 这应该可以完成工作(在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;

This also works using left joins: (Since there are no function calls or sub-selects, it is fast. Also, it's usable in most SQL engines.) 这也可以使用左联接进行工作:(由于没有函数调用或子选择,因此速度很快。而且,它在大多数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;

If I correctly understand what you need, you can try this: 如果我正确理解您的需求,则可以尝试以下操作:

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'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM