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

时间:2015-01-26 03:21:45

标签: php postgresql join

我希望我可以通过举例说明我的案例。我尽力说明问题。我有两个表,条目存储。通过产品表加入到一起,但这不是一个问题。所以这里:

条目

enter image description here

存储

enter image description here

关系:

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

输出表:

enter image description here

问题:

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

  • 查找所有条目只有一个存储空间,正数。 (绿色)
  • 使用多个存储空间,正数量查找所有条目。 (黄色)
  • 查找所有条目仅一个存储空间,零点。 (红色)
  • 使用多个存储记录但零容量查找所有条目。 (不在那里)
  • 使用不存在的存储空间查找所有条目。 (不在那里)

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

2 个答案:

答案 0 :(得分:1)

这只是显示如何为您的问题进行子选择,我会在您更新问题后更新答案:

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)

答案 1 :(得分:1)

解决方案是将“连接表”转换为视图:

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;