【问题标题】:Selecting minimum value using a subquery使用子查询选择最小值
【发布时间】:2013-03-04 02:32:14
【问题描述】:

我需要编写一个查询,从每个商家那里获取最低价格,并输出价格链接(p_link)和一些其他信息,例如商家名称+评级。

我们有一个价格表 (tgmp_prices)、一个商家表 (tgmp_merchants) 和一个附属产品 ID 表 (tgmp_affiliates)

我已经获得了获取我需要的所有价格和数据的查询:

SELECT p_id, p_m_id, p_prod_label, a_platform, p_link, p_price, m_title, m_link, m_avg_rating 
FROM tgmp_affiliates ga 
JOIN tgmp_prices p 
    ON ga.a_code = p.p_gtin 
        AND ga.a_code != '' 
JOIN tgmp_merchants m 
    ON m.m_id = p.p_m_id 
WHERE ga.site_id = '34' 
    AND p.site_id = '34' 
    AND ga.a_parent = '25573' 
    AND p_type = 'games' 
    AND m.m_hide = 0 
ORDER BY p.p_price ASC

我只需要按商家 ID(p.p_m_id 或 m.m_id)对价格进行分组,然后为每个商家选择最低价格。

SELECT p_id, p_m_id, p_prod_label, a_platform, p_link, p_price, m_title, m_link, m_avg_rating 
FROM tgmp_affiliates ga 
JOIN tgmp_prices p 
    ON ga.a_code = p.p_gtin 
        AND ga.a_code != '' 
JOIN tgmp_merchants m 
    ON m.m_id = p.p_m_id 
WHERE ga.site_id = '34' 
    AND p.site_id = '34' 
    AND ga.a_parent = '25573' 
    AND p_type = 'games' 
    AND m.m_hide = 0 
GROUP BY m.m_id
ORDER BY p.p_price ASC

如果我在 ORDER BY 之前添加 GROUP BY m.m_id,我会得到 16 个结果,每个商家 1 个。我只需要使这个价格最低。所以我尝试添加一个子查询,其中价格表(tgmp_prices)是这样连接的:

SELECT p_id, p_m_id, p_prod_label, a_platform, p_link, p_price, m_title, m_link, m_avg_rating 
FROM tgmp_affiliates ga 
JOIN tgmp_prices p 
    ON ga.a_code = p.p_gtin 
        AND ga.a_code != '' 
        AND p.p_price = ( 
            SELECT MIN(p.p_price) 
            FROM tgmp_prices 
            WHERE p.p_m_id = m.m_id
        ) 
JOIN tgmp_merchants m 
    ON m.m_id = p.p_m_id 
WHERE ga.site_id = '34' 
    AND p.site_id = '34' 
    AND ga.a_parent = '25573' 
    AND p_type = 'games' 
    AND m.m_hide = 0 
GROUP BY m.m_id
ORDER BY p.p_price ASC

这并没有给我正确的结果 - 我认为问题可能是运行子查询时 m.m_id 不可用,所以我尝试在子查询中加入商家表,但我仍然会得到相同的结果。

DDL如下:

CREATE TABLE IF NOT EXISTS `tgmp_affiliates` (
    `a_id` int(8) NOT NULL AUTO_INCREMENT,
    `site_id` int(6) NOT NULL,
    `a_parent` int(8) NOT NULL,
    `a_code` varchar(32) NOT NULL,
    `a_type` varchar(32) NOT NULL,
    `a_platform` varchar(12) NOT NULL,
    PRIMARY KEY (`a_id`),
    UNIQUE KEY `site_id` (`site_id`,`a_parent`,`a_code`,`a_type`,`a_platform`),
    KEY `a_code` (`a_code`),
    KEY `a_parent` (`a_parent`),
    KEY `a_platform` (`a_platform`),
    KEY `a_type` (`a_type`),
    KEY `site_id_2` (`site_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

-- --------------------------------------------------------

--
-- Table structure for table `tgmp_merchants`
--

CREATE TABLE IF NOT EXISTS `tgmp_merchants` (
    `m_id` int(8) NOT NULL AUTO_INCREMENT,
    `site_id` int(6) NOT NULL,
    `m_title` varchar(128) NOT NULL,
    `m_url` text NOT NULL,
    `m_link` varchar(128) NOT NULL,
    `m_favicon` text NOT NULL,
    `m_avg_rating` tinyint(1) NOT NULL,
    `m_hide` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`m_id`),
    UNIQUE KEY `m_title` (`m_title`,`m_link`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

-- --------------------------------------------------------

--
-- Table structure for table `tgmp_prices`
--

CREATE TABLE IF NOT EXISTS `tgmp_prices` (
    `p_id` int(8) NOT NULL AUTO_INCREMENT,
    `site_id` int(6) NOT NULL,
    `p_m_id` int(8) NOT NULL,
    `p_prod_label` varchar(128) NOT NULL,
    `p_gtin` varchar(64) NOT NULL,
    `p_parent` int(8) NOT NULL,
    `p_link` text NOT NULL,
    `p_price` decimal(8,2) NOT NULL,
    `p_delivery` decimal(8,2) NOT NULL,
    `p_currencey` varchar(10) NOT NULL,
    `p_avail` varchar(32) NOT NULL,
    `p_condition` varchar(32) NOT NULL,
    `p_when` datetime NOT NULL,
    `p_type` varchar(32) NOT NULL,
    `p_hide` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`p_id`),
    UNIQUE KEY `p_gtin` (`p_gtin`,`p_m_id`,`p_price`,`p_delivery`),
    KEY `p_price` (`p_price`),
    KEY `p_parent` (`p_parent`),
    KEY `site_id` (`site_id`),
    KEY `p_gtin_2` (`p_gtin`),
    KEY `p_type` (`p_type`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 ;

我现在已将查询修改为以下内容:

SELECT p_id, p_m_id, p_prod_label, a_platform, p_link, p_price, m_title, m_link, m_avg_rating 
FROM tgmp_affiliates ga 
JOIN tgmp_prices p 
    ON ga.a_code = p.p_gtin 
        AND ga.a_code != '' 
        AND p.p_price = (
            SELECT MIN(tp.p_price) FROM tgmp_prices tp
                WHERE tp.p_m_id = m.m_id
                AND tp.p_parent = '25573'
    )
JOIN tgmp_merchants m 
    ON m.m_id = p.p_m_id 
WHERE ga.site_id = '34' 
    AND p.site_id = '34' 
    AND ga.a_parent = '25573' 
    AND p_type = 'games' 
    AND m.m_hide = 0 
GROUP BY m.m_id
ORDER BY p.p_price ASC

这给出了正确数量的结果,它们非常接近正确的结果集,但我仍然没有得到每个商家的最低价格。

【问题讨论】:

  • 我认为 SELECT MIN(p.p_price) FROM tgmp_prices WHERE p.p_m_id = m.m_id 的问题总是相同且真实
  • 尝试 SELECT MIN(tp.p_price) FROM tgmp_prices tp
  • 查看您的查询很有用,因为它表明您至少尝试过自己解决问题。但为了帮助我们为您提供帮助,您应该真正考虑适用于上述情况的 DDL(和/或 SQLFIDDLE),包括所需的和相应的结果集。
  • 你试过 HAVING 吗?
  • 错误在于别名 - 子查询使用 p. 而它应该在 p_price 和 p_m_id 中使用 tgmp_prices。正如现在所写的那样,子查询应该从外部查询返回 p_price。

标签: mysql database join subquery


【解决方案1】:

也许?:

SELECT p_id,
       p_m_id,
       p_prod_label,
       a_platform,
       p_link,
       p_price,
       m_title,
       m_link,
       m_avg_rating
FROM tgmp_affiliates ga
JOIN tgmp_prices p ON ga.a_code = p.p_gtin
AND ga.a_code != ''
JOIN tgmp_merchants m ON m.m_id = p.p_m_id
WHERE ga.site_id = '34'
  AND p.site_id = '34'
  AND ga.a_parent = '25573'
  AND p_type = 'games'
  AND m.m_hide = 0
  AND p.p_price = (SELECT MIN(p2.p_price) 
                   FROM tgmp_prices p2
                   WHERE p2.p_m_id = m.m_id)
ORDER BY p.p_price ASC

【讨论】:

    【解决方案2】:

    您使用子查询作为标准,而不是将其添加为额外的记录源。这是一个调整:

    SELECT p_id, p_m_id, p_prod_label, a_platform
           , p_link, p_price, m_title, m_link, m_avg_rating, MinPrice
    FROM tgmp_affiliates ga 
    JOIN tgmp_prices p 
        ON ga.a_code = p.p_gtin 
            AND ga.a_code != ''
    JOIN tgmp_merchants m 
        ON m.m_id = p.p_m_id 
    
    JOIN
        (
            SELECT tp.p_m_id as lp_m_id, MIN(tp.p_price) AS MinPrice FROM tgmp_prices tp
                WHERE tp.p_parent = '25573'
                GROUP BY tp.p_m_id
        ) LowestPriceForEachMerchant
        ON m.m_id = LowestPriceForEachMerchant.lp_m_id
    
    WHERE ga.site_id = '34' 
        AND p.site_id = '34' 
        AND ga.a_parent = '25573' 
        AND p_type = 'games' 
        AND m.m_hide = 0 
    GROUP BY m.m_id
    ORDER BY p.p_price ASC
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2018-09-07
      • 2016-01-21
      • 2013-10-26
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      相关资源
      最近更新 更多