从两个已经连接的表中查询

Querying from two already joined tables

我希望我能通过举这个例子来解释我的情况。我尽力说明问题。我有两个 table,EntryStorage。由 Product table 连接在一起,但这不是问题。所以这里是:

条目

存储空间

关系:

1) 存储 由product_id 标识。 可以存在多个存储具有相同的product_id

加入查询:

select 
   e.id,
   e.group_id,
   e.product_id,
   e.name,
   s.volume  
from 
   entry e,
   storage s
where
   e.group_id = '840' and
   s.product_id = e.product_id

输出table:

问题:

上面的输出table很好,这就是我需要的连接结构。但是我仍然需要从这些 table 中执行查询,我需要解决 5 个案例:

是的,可能会发生存储不存在的情况。我正在使用 Postgresql 和 PHP,一旦加入 table,我就可以通过编程方式执行此操作,但是 sql 查询更清晰。谢谢!

这只是展示如何为您的问题做子select,我会在您更新问题后更新答案:

select *, (case when (x.volume = 0) then 'RED' else 'OTHER' end) as color
    select 
       e.id as id,
       e.group_id as group_id,
       e.product_id as product_id,
       e.name as name,
       s.volume as volume 
    from 
       entry e full outer join storage s
    on
       s.product_id = e.product_id
    where
       e.group_id = '840'
) as x

--已编辑--

  1. 查找只有一个存储空间的所有条目,正卷。 (绿色)

    select 
       e.id,
       e.group_id,
       e.product_id,
       e.name,
       s.volume
    from 
       entry e full outer join storage s
    on
       s.product_id = e.product_id
    where
       e.group_id = '840' and s.volume > 0
    group by e.id, e.group_id, e.product_id, e.name, s.volume
    having count(*) = 1
    
  2. 查找具有多个存储、正卷的所有条目。 (黄色)

    select 
       e.id,
       e.group_id,
       e.product_id,
       e.name,
       s.volume
    from 
       entry e full outer join storage s
    on
       s.product_id = e.product_id
    where
       e.group_id = '840' and s.volume > 0
    group by e.id, e.group_id, e.product_id, e.name, s.volume
    having count(*) > 1
    
  3. 查找只有一个存储、零卷的所有条目。 (红色)

    select 
       e.id,
       e.group_id,
       e.product_id,
       e.name,
       s.volume
    from 
       entry e full outer join storage s
    on
       s.product_id = e.product_id
    where
       e.group_id = '840' and s.volume = 0
    group by e.id, e.group_id, e.product_id, e.name, s.volume
    having count(*) = 1
    
  4. 查找具有多个存储记录但卷数为零的所有条目。 (不存在)

    select 
       e.id,
       e.group_id,
       e.product_id,
       e.name,
       s.volume
    from 
       entry e full outer join storage s
    on
       s.product_id = e.product_id
    where
       e.group_id = '840' and s.volume = 0
    group by e.id, e.group_id, e.product_id, e.name, s.volume
    having count(*) > 1
    
  5. 查找所有存储空间不存在的条目。 (不存在)

    select * from entry where product_id not in (select product_id from storage)

一个解决方案是将 "joined table" 变成一个视图:

CREATE VIEW entry_products AS
  SELECT e.id, e.group_id, e.product_id, e.name, s.volume  
  FROM entry e
  LEFT JOIN storage s ON s.product_id = e.product_id;

您现在可以查询视图:

单个存储的条目,正体积:

SELECT id, group_id, product_id, name, volume
FROM entry_products
WHERE volume > 0
GROUP BY id, group_id, product_id, name, volume
HAVING count(*) = 1;

多次存储的条目,正卷:

SELECT id, group_id, product_id, name, volume
FROM entry_products
WHERE volume > 0
GROUP BY id, group_id, product_id, name, volume
HAVING count(*) > 1;

单个存储的条目,零体积:

SELECT id, group_id, product_id, name, volume
FROM entry_products
WHERE volume = 0
GROUP BY id, group_id, product_id, name, volume
HAVING count(*) = 1;

具有多重存储、零体积的条目:

SELECT id, group_id, product_id, name, volume
FROM entry_products
WHERE volume = 0
GROUP BY id, group_id, product_id, name, volume
HAVING count(*) > 1;

无存储空间:

SELECT *
FROM entry_products
WHERE volume IS NULL;

请注意,我将 e.group_id = 840 过滤器排除在视图和查询之外。如果您只使用 group_id = 840 的查询,那么您可以将它放回视图中;如果您在不同时间使用不同的 group_id 值,则将相应的 WHERE 子句添加到视图中的每个查询。

请注意,您可以将上述每个查询包装在单独的视图中,以使查询更容易:

-- Single storage, positive volume
CREATE VIEW ep_one_pos AS
  SELECT id, group_id, product_id, name, volume
  FROM entry_products
  WHERE volume > 0
  GROUP BY id, group_id, product_id, name, volume
  HAVING count(*) = 1;

然后你可以简单地:

SELECT *
FROM ep_one_pos
WHERE group_id = 840;