FROM中的子查询不在Oracle SQL中工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FROM中的子查询不在Oracle SQL中工作相关的知识,希望对你有一定的参考价值。

我正在努力将查询从WHERE部分中的子查询转换为FROM部分。

据我所知,FROM子句将返回一个表,我称之为“product_locations”,然后我的外部查询可以从该表中检索信息。我无法看到外部查询是否在此时工作,因为我遇到了一个错误,我错过了一个右括号。在这一点上,我认为我的主要问题是不了解如何正确识别构成子查询的IN子句的两个部分。

这是原始查询:

SELECT size_option, 
       product.product_name
FROM   sizes
JOIN   available_in ON sizes.sized_id = available_in.sizes_id
JOIN   product ON product.product_id = available_in.product_id
WHERE (SELECT COUNT (store_name)
       FROM store_location IN (SELECT COUNT (store_location_id)
       FROM sells
       JOIN product ON sells.product_id = product.product_id
       GROUP BY sells.store_location)

这是我正在尝试的查询:

SELECT size_option, 
       product_location.product_name 
FROM   (SELECT COUNT(store_name)
       FROM   store_location) IN (SELECT COUNT (store_location_id)
       FROM sells
       JOIN product ON sells.product_id = product.product_id
GROUP BY sells.store_location_id) product_location
JOIN   sizes ON sizes.size_option = product_location.size_option
JOIN   available_in ON sizes.sizes_id = available_in.sizes_id
JOIN   product ON product.product_id = available_in.product_id

和我得到的错误:

SELECT size_option, 
       product_location.product_name 
FROM   (SELECT COUNT(store_name)
       FROM   store_location) IN (SELECT COUNT (store_location_id)
       FROM sells
       JOIN product ON sells.product_id = product.product_id
GROUP BY sells.store_location_id) product_location
JOIN   sizes ON sizes.size_option = product_location.size_option
JOIN   available_in ON sizes.sizes_id = available_in.sizes_id
JOIN   product ON product.product_id = available_in.product_id
Error at Command Line : 4 Column : 31
Error report -
SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 -  "SQL command not properly ended"
*Cause:    
*Action:

这是我的编辑器picture of the error中的错误图片

这是ERD enter image description here

答案

在FROM子句中使用IN condition可能会让您感到悲伤,因为“条件指定了一个或多个表达式和逻辑(布尔)运算符的组合,并返回值TRUE,FALSE或UNKNOWN。” (见documentation)。因此,像(SELECT ...)IN(SELECT ...)这样的构造 - 如果语法正确 - 将返回true,false或unknown - 这在WHERE子句中有用(不在FROM子句中)。

在您的一条评论中,您正在解释......“目的是展示所有地点都可用的所有产品。”

使用包含5个表的小型测试数据集(请参阅dbfiddle),以下查询可为您提供查找解决方案的起点:

-- Find the store count for each product (table SELLS)
-- and return all product_ids that are available everywhere (STORE_LOCATION count)

select product_id
from (
  select 
    product_id
  , count( store_location_id ) store_count
  from sells
  group by product_id
  having count( store_location_id ) = ( select count(*) from store_location )
) ;

-- result
PRODUCT_ID
----------
        10

替代

-- ---------------------------------------------------
-- use analytics -> we don't need GROUP BY and HAVING
-- ---------------------------------------------------
-- 1  count all store_locations (SL)
-- 2  count the amount of stores a product is located in (S)
-- 3  JOIN the 2 result sets (equijoin)
-- 4  return the product_id found
-- NOTE: we are working with Oracle -> don't use AS when defining table aliases (AS can be used for column aliases)

select product_id -- 4
from ( 
  select count(*) store_count from store_location  -- 1
) SL join (
  select unique 
    product_id
  , count( store_location_id ) over ( partition by product_id ) store_count -- 2
  from sells
) S on SL.store_count = S.store_count -- 3
;

-- result
PRODUCT_ID
----------
        10

一旦获得了正确的product_id,就可以“使用JOIN”“查找”查询所需的剩余表,并将所有必需的列名(包括表别名)写入SELECT。例如。

select 
  S.product_id
, P.product_name
, SZ.size_option
from ( 
  select count(*) store_count from store_location 
) SL join (
  select unique
    product_id
  , count( store_location_id ) over ( partition by product_id ) store_count
  from sells
) S on SL.store_count = S.store_count 
join product P       on S.product_id = P.product_id
join available_in AI on AI.product_id = P.product_id 
join sizes SZ        on AI.sizes_id = SZ.sizes_id
;

-- result
PRODUCT_ID PRODUCT_N SIZE_OP
---------- --------- -------
        10 product10 option1
        10 product10 option2
另一答案

你可以在下面查询

SELECT size_option, 
       product_location.product_name,
      (
       SELECT COUNT(store_name)
       FROM   store_location
       )  as store_name_cnt,
       (
       SELECT COUNT (store_location_id)
       FROM sells
       JOIN product ON sells.product_id = product.product_id
    GROUP BY sells.store_location_id
     ) as location_count
    from product_location
JOIN   sizes ON sizes.size_option = product_location.size_option
JOIN   available_in ON sizes.sizes_id = available_in.sizes_id

你的查询错误

SELECT size_option, 
       product_location.product_name 
FROM   (SELECT COUNT(store_name) --invalid from 
       FROM   store_location) 
      IN (SELECT COUNT (store_location_id) -- there is no where but you use in
       FROM sells
       JOIN product ON sells.product_id = product.product_id
GROUP BY sells.store_location_id) product_location -- inconsistent table alias
JOIN   sizes ON sizes.size_option = product_location.size_option
JOIN   available_in ON sizes.sizes_id = available_in.sizes_id
JOIN   product ON product.product_id = available_in.product_id
另一答案

根据评论中的OP:目的是显示所有位置可用的所有产品。

考虑连接两个聚合查询派生表(或FROMJOIN子句中的子查询):

  1. 一个计算特定产品的商店
  2. 一个计算所有产品的商店

然后通过相应的product_id和store_count值加入子查询。请务必使用表别名来提高可读性。

SELECT s.size_option, 
       p.product_name
FROM   sizes AS s
JOIN   available_in AS a ON s.sized_id = a.sizes_id
JOIN   product AS p ON p.product_id = a.product_id
JOIN  
      --- STORE COUNT BY PRODUCT
      (
       SELECT sub_p.product_id, COUNT(sl.store_location_id) AS store_count
       FROM sells AS sl
       JOIN product AS sub_p ON sl.product_id = sub_p.product_id
       GROUP BY sub_p.product_id
      ) AS agg_p 
  ON agg_p.product_id = p.product_id

JOIN  
      --- STORE COUNT ACROSS ALL PRODUCTS
      (
       SELECT COUNT(sl.store_location_id) AS store_count
       FROM sells AS sl
       JOIN product AS sub_p ON sl.product_id = sub_p.product_id
      ) AS agg_s 
  ON agg_s.store_count = agg_p.store_count

以上是关于FROM中的子查询不在Oracle SQL中工作的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL,在 SELECT 标头中的子查询中返回唯一(最大)行(在 FROM、WHERE 之前)

选择语句中的子查询如何在 oracle 中工作

这个 SQL 查询怎么会在 Oracle SQL Developer 中工作而不是在代码中工作?

使用 from 中的子查询优化 SQL

MySQL的子查询中FROM和EXISTS子句的使用教程

使用 FROM 子句中的子查询进行联接操作中的 SQL 语法错误