您如何grouby并检查组是否包含2个或更多给定值?

时间:2019-06-14 19:50:51

标签: mysql

我有一个带有建筑物名称的表,例如A,B,C。这些建筑物名称可以重复。我还有另外一个专栏发言。例如第1层,第2层。同样,每个建筑物可能有多个第1层。第三列显示对象,例如电视,砖块,风扇。 我想检查建筑物与相应楼层的每种组合,例如A楼-1楼,A楼-2楼,如果存在对象“砖”,则必须存在“墙”。

示例数据: 对于每个建筑物和位置,如果存在“ WALL”,“ WINDOW”,“ WINDOW1”或“ WINDOW2”,则其他标志

BUILDING  LOCATION  OBJECT   
A         FLOOR1    WINDOW1  
A         FLOOR1    WINDOW  
A         FLOOR1    WINDOW2 
A         FLOOR2    WALL  
B         FLOOR1    WALL  
C         FLOOR1    WALL  
C         FLOOR1    WINDOW

期望的输出

BUILDING  LOCATION  ACTION    
A         FLOOR2    FLAG
B         FLOOR1    FLAG

我尝试使用GROUP BY,DISTINCT,WHERE EXISTS,但是我似乎无法提出正确的逻辑。

3 个答案:

答案 0 :(得分:1)

不存在:

select distinct t.building, t.location, 'FLAG' action
from tablename t
where object = 'WALL'
and not exists (
  select 1 from tablename
  where building = t.building and location = t.location
  and object like 'WINDOW%'
)

请参见demo
结果:

| building | location | action |
| -------- | -------- | ------ |
| A        | FLOOR2   | FLAG   |
| B        | FLOOR1   | FLAG   |

答案 1 :(得分:0)

SQL DEMO

SELECT building, 
        location,  
        MAX(CASE WHEN object = 'WALL' THEN 1 ELSE 0 END) as has_walls,
        MAX(CASE WHEN object IN ('WINDOW', 'WINDOW1', 'WINDOW2') THEN 1 ELSE 0 END)  as has_windows
 FROM tablename
 GROUP BY building, location
 HAVING 
        has_walls <> has_windows;

因此,如果您有任何墙,MAX()将返回1,与Windows相同。

这带来了WALL不带WINDOWS,但是也带来了WINDOWS不带WALLS

让我知道您是否需要进一步提炼

如果您希望WALLS不包含WINDOWS

 SELECT building, 
        location,  
        MAX(CASE WHEN object = 'WALL' THEN 1 ELSE 0 END) as has_walls,
        MAX(CASE WHEN object IN ('WINDOW', 'WINDOW1', 'WINDOW2') THEN 1 ELSE 0 END)  as has_windows
 FROM tablename
 GROUP BY building, location
 HAVING 
        has_walls > 0 
    AND has_windows = 0

答案 2 :(得分:0)

我实际上会以与forpas相同的方式编写查询。但这是另一种方式:

select BUILDING, LOCATION, 'FLAG' as `ACTION`
from my_table
group by BUILDING, LOCATION
having bit_or(OBJECT = 'WALL') -- at least one OBJECT is 'WALL'
   and bit_and(OBJECT not rlike 'WINDOW[0-9]*') -- no OBJECT matches 'WINDOW[number]'

db-fiddle

它比较短,但可能不容易理解。