【问题标题】:select owner who has all types of bikes选择拥有所有类型自行车的车主
【发布时间】:2023-03-28 00:00:01
【问题描述】:

下面是两张桌子的图片,车主和车辆。 我需要找出拥有所有类型自行车的车主。
例子: O_id 100,O_id 101,O_id 102 有 V_id=1 的自行车,但是
O_id 103 拥有所有类型的自行车(V_id = 1 和 V_id = 5)
如何编写查询来获取这些详细信息?
我的查询:

select o.o_id from owner o,vehicles v where
o.v_id = v.v_id where v_type = 'bike'

这是显示所有拥有自行车的车主,而不是拥有所有自行车的车主

【问题讨论】:

    标签: sql database postgresql join subquery


    【解决方案1】:

    这里有两个使用子查询和连接查询的查询:

    架构:

    drop table vehicle;
    drop table owner;
    create table vehicle(V_id int, V_type varchar(20));
    create table owner(O_id int , V_id int);
    insert into vehicle values(1,'Bike');
    insert into vehicle values(2,'Car');
    insert into vehicle values(3,'Car');
    insert into vehicle values(4,'Car');
    insert into vehicle values(5,'bike');
    insert into owner values(100, 1);
    insert into owner values(101, 1);
    insert into owner values(102, 1);
    insert into owner values(103, 1);
    insert into owner values(100, 2);
    insert into owner values(101, 3);
    insert into owner values(103, 5);
    

    子查询:

    postgres=# select count(*) as bike_count, O_id  from owner where V_id in (
    postgres(#    select V_id from vehicle where upper(V_type) = 'BIKE'
    postgres(# )
    postgres-# group by 2
    postgres-# order by 1 desc
    postgres-# ;
     bike_count | o_id
    ------------+------
          2 |  103
          1 |  101
          1 |  100
          1 |  102
    (4 rows)
    

    加入查询:

    postgres=# select count(*) as bike_count, O_id  from owner o join vehicle v using(v_id)
    postgres-# where  upper(v.V_type) = 'BIKE'
    postgres-# group by 2
    postgres-# order by 1 desc
    postgres-# ;
     bike_count | o_id
    ------------+------
          2 |  103
          1 |  100
          1 |  102
          1 |  101
    (4 rows)
    

    如果您只需要所有者,可以将查询限制为 1 个

    【讨论】:

    • 如果没有一个车主拥有所有自行车怎么办?
    • 如果您的查询是让车主拥有所有自行车,因此如果没有车主拥有所有(1 辆或更多)自行车,则答案为 NONE。正确的?或者我错过了什么。
    • 正确。但是您的查询没有返回任何内容吗?我不这么认为。还是我错过了什么?
    • 是的,确实如此。只需运行删除“从所有者中删除 V_id in (1, 5);”然后运行选择查询。它返回无。
    • 你在开玩笑吧?好吧,你有我的反对意见。它不起作用。
    【解决方案2】:
    with bykes as (
        select array_agg(v_id) as byke_ids
        from vehicle
        where lower(v_type) = 'byke'
    ), owner as (
        select o_id, array_agg(v_id) as v_ids
        from owner
        group by o_id
    )
    select o_id
    from owner cross join bykes
    where v_ids @> byke_ids
    ;
    o_id 
    ------
    103
    

    架构:

    create table owner (
        o_id int,
        v_id int
    );
    create table vehicle (
        v_id int,
        v_type text
    );
    insert into owner (o_id, v_id) values
    (100, 1),
    (101, 1),
    (102, 1),
    (103, 1),
    (100, 2),
    (101, 3),
    (103, 5);
    
    insert into vehicle (v_id, v_type) values
    (1, 'Byke'),
    (2, 'Car'),
    (3, 'Car'),
    (4, 'Car'),
    (5, 'byke');
    

    【讨论】:

      【解决方案3】:

      按您想要获取的o_id分组。
      只取那些拥有相同数量 (count(v_id)) 的自行车组,这些组的自行车总数相同 (select count(*) from vehicles where v_type = 'bike')

      select o.o_id 
      from owner o
      join vehicles v on o.v_id = v.v_id
      where v.v_type = 'bike'
      group by o.o_id 
      having count(distinct v.v_id) = (select count(*) from vehicles where v_type = 'bike')
      

      【讨论】:

      • 可以使用子查询来完成吗?老实说,我觉得这有点难以理解
      • 那是使用子查询。我在答案中添加解释
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      相关资源
      最近更新 更多