Mysql
使用子查詢選擇最小值
我需要編寫一個查詢來從每個商家那裡獲取最低價格並輸出價格連結(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
這給出了正確數量的結果,它們非常接近正確的結果集,但我仍然沒有得到每個商家的最低價格。
稍微修改您的第二個查詢,將為您提供商家 ID 和最低價格(在所有通過條件的產品中 - 我想這就是您想要的):
SELECT p.p_m_id, MIN(p_price) AS min_p_price 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.p_type = 'games' AND m.m_hide = 0 GROUP BY p.p_m_id ;
然後,您可以將其作為派生表加入到您需要從結果中獲取數據的所有表中:
SELECT m.*, p.*, ga.* -- whatever columns you want 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 p.p_m_id, MIN(p_price) AS p_price 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.p_type = 'games' AND m.m_hide = 0 GROUP BY p.p_m_id ) AS tmp ON tmp.p_m_id = p.p_m_id AND tmp.p_price = p.p_price WHERE ga.site_id = '34' AND p.site_id = '34' AND ga.a_parent = '25573' AND p.p_type = 'games' ORDER BY p.p_price ;