MySQL:查询并不总是返回多个商店的最新最低价格

标签 mysql function min

如果只有单个商店的价格信息,下面的 SQL 将返回每种产品的最新最低价格,如果有多个商店的价格信息,则并不总是返回最新的最低价格!?

想要的结果

从所有商店的最新价格信息中返回产品的最低价格,因此如果有 6 家商店,它将显示 6 家商店中每家商店的最新价格记录中的最低价格。

如果所有商店价格记录中的最新价格都相同,并且更新日期也相同,则可以按商店对记录进行排序,以选择相关产品的价格。

{product id} 是根据显示的产品传入的值。

SQL

SELECT `vsp`.`prod_id`
, `vsp`.`price`
, `vsp`.`store`
, `vsp`.`updated`
FROM `price` `vsp`
WHERE NOT EXISTS
(
    SELECT * 
    FROM `price` `vsp2`
    WHERE `vsp2`.`prod_id` = `vsp`.`prod_id`
    AND `vsp`.`prod_id` = {product id}
    AND (`vsp2`.`updated` > `vsp`.`updated` OR (`vsp2`.`updated` = `vsp`.`updated` AND `vsp2`.`price` < `vsp`.`price`))
) AND `vsp`.`prod_id` = {product id}

价格

prod_id     | price     | store | updated
--------------------------------------------------------
product 1   | 1.99      | 1     | 2016-01-20 00:00:00
product 2   | 1.49      | 1     | 2016-01-20 00:10:00
product 2   | 1.19      | 2     | 2016-01-20 00:00:00
product 3   | 12.49     | 1     | 2016-01-20 00:00:00
product 3   | 12.49     | 2     | 2016-01-20 00:00:00
product 4   | 9.89      | 1     | 2016-01-20 00:00:00
product 5   | 10.00     | 1     | 2016-01-20 00:10:00
product 5   | 9.99      | 2     | 2016-01-20 00:00:00
product 5   | 10.49     | 3     | 2016-01-20 00:00:00

预期输出

product 1   | 1.99      | 1     | 2016-01-20 00:00:00
product 2   | 1.49      | 1     | 2016-01-20 00:10:00
product 3   | 12.49     | 1     | 2016-01-20 00:00:00
product 4   | 9.89      | 1     | 2016-01-20 00:00:00
product 5   | 9.99      | 2     | 2016-01-20 00:00:00

电流输出

product 1   | 1.99      | 1     | 2016-01-20 00:00:00
product 2   | 1.49      | 1     | 2016-01-20 00:10:00
product 3   | 12.49     | 1     | 2016-01-20 00:00:00
product 4   | 9.89      | 1     | 2016-01-20 00:00:00
product 5   | 10.00     | 1     | 2016-01-20 00:10:00

更新#1

选择本身看起来工作得很好,当我将 prodId 约束添加到查询中时,只返回一个价格,现在的问题是,如果我将 select 语句添加到一个函数,它会给出以下结果即使我在单独运行选择时只看到返回一个值,也会出现错误。

Result consisted of more than one row

SQL函数

CREATE FUNCTION FN_GET_SET_LOWEST_PRICE (`prodId` VARCHAR(20))
RETURNS DOUBLE
BEGIN
    DECLARE `latestPrice` DOUBLE(7,2) DEFAULT 0;

    SELECT p3.price
    INTO `latestPrice`
    FROM price p3
    INNER JOIN
    (
        SELECT p1.prod_id, MIN(p1.price) AS minPrice
        FROM price p1
        INNER JOIN
        (
            SELECT prod_id, MIN(updated) AS minUpdated
            FROM price
            GROUP BY prod_id
        ) p2
        ON p1.prod_id = p2.prod_id AND p1.updated = p2.minUpdated
        GROUP BY p1.prod_id
    ) t
    ON p3.prod_id = t.prod_id AND p3.price = t.minPrice
    WHERE p3.prod_id = prodId;

    RETURN `latestPrice`;
END//
DELIMITER ;

最佳答案

我倾向于使用一系列内部联接来获取结果集,而不是在 WHERE 子句中使用复杂的子查询,因为后者难以阅读。

SELECT p3.prod_id, p3.price, p3.store, p3.updated
FROM price p3
INNER JOIN
(
    SELECT p1.prod_id, MIN(p1.price) AS minPrice
    FROM price p1
    INNER JOIN
    (
        SELECT prod_id, MIN(updated) AS minUpdated
        FROM price
        GROUP BY prod_id
    ) p2
    ON p1.prod_id = p2.prod_id AND p1.updated = p2.minUpdated
    GROUP BY p1.prod_id
) t
ON p3.prod_id = t.prod_id AND p3.price = t.minPrice

点击下面的链接即可运行演示:

SQLFiddle

更新:

如果您想像函数一样使用此查询,则必须创建一个存储过程。这样做的原因是函数必须仅返回一个值。即使您设计一个应该只返回单个值的查询,MySQL 仍然会提示。

尝试以下操作:

CREATE PROCEDURE FN_GET_SET_LOWEST_PRICE(prodId VARCHAR(20))
BEGIN
    SELECT p3.price
    FROM price p3
    INNER JOIN
    (
        SELECT p1.prod_id, MIN(p1.price) AS minPrice
        FROM price p1
        INNER JOIN
        (
            SELECT prod_id, MIN(updated) AS minUpdated
            FROM price
            GROUP BY prod_id
        ) p2
        ON p1.prod_id = p2.prod_id AND p1.updated = p2.minUpdated
        GROUP BY p1.prod_id
    ) t
    ON p3.prod_id = t.prod_id AND p3.price = t.minPrice
    WHERE p3.prod_id = prodId;
END

关于MySQL:查询并不总是返回多个商店的最新最低价格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34914162/

相关文章:

PHP 将值插入两个表并将这些表中的键插入链接表

mysql - 删除已经在另一个表中的行

php - SQL 连接与连接表中的 where 子句

javascript - 比较 JavaScript 中的 2 个函数

python - 在字典中查找最小非零值 (Python)

php - 为什么存储在 session 变量中的数组计数会加倍?

javascript - 使用 'if' 重定向

javascript - 带有局部参数的 onclick 全局函数

c++ - 有效地从未排序的数组中获取前 50 个最高数字

java - Java 中的最小/最大 lambda 表达式