加入价格表中所有产品的最新价格

时间:2019-06-15 15:25:57

标签: mysql sql join select

我有一个产品和一个价格表(带有产品ID,价格和时间戳列)。现在,我需要加入最新价格的简单产品选择。

简单联接将选择表中第一个保存的价格,而不是最新的。

package com.rinventor.rinventedmod.blocks.advanced.gui;

import com.rinventor.rinventedmod.Main;
import com.rinventor.rinventedmod.blocks.advanced.container.ContainerMoneyChest;
import com.rinventor.rinventedmod.blocks.advanced.tileentity.TileEntityMoneyChest;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;

public class GuiMoneyChest extends GuiContainer {

    private static final ResourceLocation GUI_CHEST = new ResourceLocation(Main.MODID + ":textures/gui/money_chest.png");
    private final InventoryPlayer playerInventory;
    private final TileEntityMoneyChest temc;

    public GuiMoneyChest(InventoryPlayer playerInventory, TileEntityMoneyChest chestInventory, EntityPlayer player) {

        super(new ContainerMoneyChest(playerInventory, chestInventory, player));
        this.playerInventory = playerInventory;
        this.temc = chestInventory;

        this.xSize = 176;
        this.ySize = 154;
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        this.fontRenderer.drawString(this.temc.getDisplayName().getUnformattedText(), 14, 4, 0);//3120942-green
        this.fontRenderer.drawString(this.playerInventory.getDisplayName().getUnformattedText(), 8, this.ySize-93, 0);
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
        this.mc.getTextureManager().bindTexture(GUI_CHEST);
        this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
    }
}

因此,我尝试加入选择最新时间戳的方法,但这只会返回所有记录的最新时间戳,而不是按product_price:

@font-face{
    font-family:Material Design Icons;
    src:url(../fonts/materialdesignicons-webfont.abb4e749.eot);
    src:url(../fonts/materialdesignicons-webfont.abb4e749.eot?#iefix&v=2.8.94) format("embedded-opentype"),
    url(../fonts/materialdesignicons-webfont.45911874.woff2) format("woff2"),
    url(../fonts/materialdesignicons-webfont.4b882ad4.woff) format("woff"),
    url(../fonts/materialdesignicons-webfont.d15c1216.ttf) format("truetype"),
    url(../img/materialdesignicons-webfont.ae4dbede.svg#materialdesigniconsregular) format("svg");
    font-weight:400;
    font-style:normal
}

是否有一种明智/正确的方法来选择所有产品的最新价格?

2 个答案:

答案 0 :(得分:0)

您已经接近,但在子查询中需要一个GROUP BY

SELECT p.*, pp.*
FROM products p LEFT JOIN
     (SELECT product_id, MAX(timestamp) as timestamp
      FROM product_prices
      GROUP BY product_id
     ) pp 
     ON pp.product_id = p.id;

目前尚不清楚ranking列的含义。它仅在您的查询中使用,在问题的其他地方未提及。

如果要整个product_price行,则可以使用其他JOIN

SELECT p.*, pp.*
FROM products p JOIN
     product_prices pp
     ON pp.product_id = p.id LEFT JOIN
     (SELECT product_id, MAX(timestamp) as timestamp
      FROM product_prices
      GROUP BY product_id
     ) ppm
     ON ppm.product_id = p.id AND ppm.timestamp = pp.timestamp;

答案 1 :(得分:0)

我认为您需要在这里加入两个。第一次联接直接连接到product_prices表,以引入该表中所需的列。第二个联接是一个子查询,该子查询按产品汇总product_prices,以查找每个产品的最新条目。然后,第二个联接将限制来自第一个联接的完整结果。

SELECT p.*, pp1.*
FROM products p
LEFT JOIN product_prices pp1
    ON p.id = pp1.product_id
INNER JOIN
(
    SELECT product_id, MAX(timestamp) AS max_ts
    FROM product_prices
    GROUP BY product_id
) pp2
    ON pp1.product_id = pp2.product_id AND
       pp1.timestamp = pp2.max_ts;

如果您使用的是MySQL 8+,那么我们可以在此处利用窗口功能:

WITH cte AS (
    SELECT p.*, pp1.*,
        ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY pp.timestamp DESC) rn
    FROM products p
    LEFT JOIN product_prices pp
        ON p.id = pp.product_id
)

SELECT *
FROM cte
WHERE rn = 1;