在JOIN MAX(date)MYSQL之后使用MIN值

时间:2019-11-09 16:45:44

标签: mysql

我有3张桌子。 制造商产品价格

我想获取产品的最后价格,然后选择产品的最低价格。

桌子制造商:

# manufacturers
id        name
 1        Manufacturer 1
 2        Manufacturer 2

餐桌产品:

# products
id        name
 1        Product 1
 2        Product 2

价格表

# prices
id        price        manufacturerId        createdAt    
 1           10                     1        '2019-09-09 00:00:00'
 2           20                     1        '2019-09-10 00:00:00'
 3           11                     2        '2019-09-09 00:00:00'
 4           21                     2        '2019-09-10 00:00:00'

完整代码:

DROP DATABASE if exists ssg ;
CREATE DATABASE ssg;
USE ssg;

# Create database manufacturers
CREATE TABLE manufacturers (id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                            name VARCHAR(256) NOT NULL);
# Insert value
INSERT INTO manufacturers (name) VALUES ('Manufacturer 1');
INSERT INTO manufacturers (name) VALUES ('Manufacturer 2');


# Create database products
CREATE TABLE products (id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                       name VARCHAR(256) NOT NULL);
# Insert value
INSERT INTO products (name) VALUES ('Product 1');

# Create database prices
CREATE TABLE prices (id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                     productId INT(11) UNSIGNED NOT NULL,
                     price BIGINT UNSIGNED NOT NULL,
                     manufacturerId INT(11) UNSIGNED NOT NULL,
                     createdAt DATETIME NOT NULL);
# Insert value
INSERT INTO prices (productId, price, manufacturerId, createdAt) VALUES (1, 10, 1, '2019-09-09 00:00:00');
INSERT INTO prices (productId, price, manufacturerId, createdAt) VALUES (1, 20, 1, '2019-09-10 00:00:00');
INSERT INTO prices (productId, price, manufacturerId, createdAt)VALUES (1, 11, 2, '2019-09-09 00:00:00');
INSERT INTO prices (productId, price, manufacturerId, createdAt)VALUES (1, 21, 2, '2019-09-10 00:00:00');

# Query
SELECT products.id, products.name, lastValue.price as latestPrice, lastValue.manufacturerId
FROM products
LEFT JOIN(
        SELECT productId, COUNT(DISTINCT manufacturerId) AS total
        FROM prices
        GROUP BY prices.productId) counts ON counts.productId = products.id
        LEFT JOIN (
            SELECT prices.*
            FROM (
                    SELECT productId, MAX(createdAt) createdAt
                    FROM prices
                    GROUP BY productId) latest
                    JOIN prices ON latest.productId = prices.productId
                    AND prices.createdAt = latest.createdAt
            ) lastValue
        ON lastValue.productId = products.id

然后我得到了

id        name        latestPrice        manufacturerId
 1        Product 1            20                     1
 1        Product 1            21                     2

那么我怎么只能用MIN的MIN来接收产品。

我必须将其发布在http://sqlfiddle.com/#!9/418cb7/1中。请先“构建架构”,然后“运行SQL”

对不起,我的英语不好。

1 个答案:

答案 0 :(得分:1)

在MySQL 8.0中,您只能使用窗口函数来做到这一点:

select id, name, price, manufacturerId
from (
    select 
        t.*,
        rank() over(order by price) rn2
    from (
        select
            p.id,
            p.name,
            i.price,
            i.manufacturerId,
            rank() over(partition by p.id order by i.createdAt desc) rn1
        from products p
        inner join prices i on i.productId = p.id
    ) t
    where rn1 = 1
) t
where rn2 = 1

此短语为:

  • 首先按降序对每种产品的价格进行排名,然后根据每种产品的最新价格进行过滤
  • 然后按升序对所有最新价格进行排名,并按最低价格进行过滤

Demo on DB Fiddle

id | name      | price | manufacturerId
-: | :-------- | ----: | -------------:
 1 | Product 1 |    20 |              1