MYSQL以最低值获取记录 View的SELECT包含FROM子句中的子查询

Sat*_*aNL 4 mysql sql view

我一直在研究这个问题,这让我疯狂.

我有一个产品表和一个包含子产品的表.简而言之,我想创建一个包含产品数据的视图,以及子产品的最低(折扣)价格.(想想一件衬衫,有几个子产品(颜色/尺码)等)

其次我想在VIEW中使用这个查询,这部分让我疯狂.

我现在的查询:

  SELECT m.* from product_items m join
  (select product_id, min(price_discount) md 
       from product_items group by product_id) mm
  on m.product_id=mm.product_id and m.price_discount=md
Run Code Online (Sandbox Code Playgroud)

这个查询正在运行,我得到了很好的结果.但现在我想创建一个视图(vw_product_lowest).然后是错误:ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause

任何人都可以帮我将该查询转换为兼容的VIEW查询吗?谢谢!

egg*_*yal 9

你有几个选择:

  1. 将子查询放入视图中(可能很慢,因为生成的视图没有用于执行后续连接的索引):

    CREATE VIEW mm AS
      SELECT   product_id, MIN(price_discount) price_discount
      FROM     product_items
      GROUP BY product_id
    ;
    
    CREATE VIEW my_view AS
      SELECT * FROM product_items m NATURAL JOIN mm
    ;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用相关子查询(也可能很慢,因为必须针对表中的每个记录评估子查询 - 使用复合索引可以获得最佳性能(product_id, price_discount)):

    CREATE VIEW my_view AS
      SELECT * FROM product_items m WHERE price_discount = (
        SELECT MIN(mm.price_discount)
        FROM   product_items mm
        WHERE  mm.product_id = m.product_id
      )
    ;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用EXISTS策略优化相关子查询(也将受益于复合索引(product_id, price_discount)):

    CREATE VIEW my_view AS
      SELECT * FROM product_items m WHERE NOT EXISTS (
        SELECT 1
        FROM   product_items mm
        WHERE  mm.product_id     = m.product_id
           AND mm.price_discount < m.price_discount
        LIMIT  1
      )
    ;
    
    Run Code Online (Sandbox Code Playgroud)


Joh*_*Woo 6

根据手册,VIEW不能包含子查询.如果您真的想VIEW在查询上创建一个,则需要为子查询创建一个单独的视图,例如

第一个视图

CREATE VIEW MinimumPrice
AS 
SELECT  product_id, MIN(price_discount) md 
FROM    product_items 
GROUP   BY product_id
Run Code Online (Sandbox Code Playgroud)

第二个视图

CREATE VIEW MinimumPriceList
AS 
SELECT  m.* 
FROM    product_items m 
        INNER JOIN MinimumPrice mm 
            ON  m.product_id = mm.product_id AND 
                m.price_discount = mm.md
Run Code Online (Sandbox Code Playgroud)

要查询MAIN VIEW,

SELECT * FROM MinimumPriceList
Run Code Online (Sandbox Code Playgroud)

视图定义受以下限制约束:FROM MySQL MANUAL

  • SELECT语句不能在FROM子句中包含子查询.
  • SELECT语句不能引用系统或用户变量.
  • 在存储的程序中,定义不能引用程序参数或局部变量.
  • ....