【问题标题】:Querying from two already joined tables从两个已经连接的表中查询
【发布时间】:2015-01-26 03:21:45
【问题描述】:

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

参赛作品

存储

关系:

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

输出表:

问题:

上面的输出表很好,这是我需要的joined结构。但是我仍然需要从这些表中执行查询,我需要解决 5 种情况:

  • 查找所有条目只有一个存储,正容量。 (绿色)
  • 查找所有条目多重存储,正体积。 (黄色)
  • 查找所有条目只有一个存储,零容量。 (红色)
  • 查找所有具有多条存储记录但容量为零条目。 (不存在)
  • 查找所有条目不存在的存储。 (不存在)

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

【问题讨论】:

  • 如果它有一个存储零容量多个存储零容量,它必须是什么颜色?
  • 好点..也许我也必须将其添加到案例列表中?我还不知道

标签: php postgresql join


【解决方案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;

【讨论】:

  • @ColourDalnet:我很高兴从您的回答中看到您已经向我学习! {;-P
  • 我喜欢视图概念.. 但它不需要我经常更新吗?
  • @muffin:视图背后的整个想法是,每次查询视图时它都会从基础表中提取数据。因此,无论何时使用视图,您都可以从表中获取最新信息。在构建此类层次结构(您可以从视图创建视图等)以及使用子查询时,您应该将结果视为表格格式的新数据集。 PostgreSQL 称之为“关系”。
  • 哦对了,我在考虑物化视图而不是常规视图。我会接受这个作为答案谢谢!
【解决方案2】:

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

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)

【讨论】:

  • 我实际上不必为它“着色”。我只需要对这 5 种情况中的每一种进行查询。基本上我需要这 5 种情况下的 5 条选择语句。谢谢!
  • 你的意思是把查询分开成5个查询吗?
  • 是的。每个案例 1 个查询。
  • 好的,我会一一更新,发现错误欢迎评论。
  • 完成了,检查一下 ;)
猜你喜欢
  • 1970-01-01
  • 2015-11-02
  • 2014-11-07
  • 2016-05-27
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多