[英]How to fetch a row which is related to multiple rows in another table?
I have some tables: 我有一些桌子:
CREATE TABLE `ws_shop_product` (
`product_id` int(10) unsigned NOT NULL AUTO_INCREMENT
`product_title` varchar(255) COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM AUTO_INCREMENT=14499 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
CREATE TABLE `ws_system_admin` (
`admin_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`admin_username` varchar(255) NOT NULL,
`admin_password` char(40) NOT NULL,
PRIMARY KEY (`admin_id`)
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
CREATE TABLE `ws_shop_product-updated` (
`updated_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`updated_product` int(10) unsigned DEFAULT NULL,
`updated_admin` int(10) unsigned DEFAULT NULL,
`updated_date` datetime DEFAULT NULL,
PRIMARY KEY (`updated_id`),
KEY `updated_product` (`updated_product`),
KEY `updated_admin` (`updated_admin`)
) ENGINE=MyISAM AUTO_INCREMENT=42384 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
Whenever a product
has been changed in the CMS, one row will insert into the ws_shop_product-updated
which keep the admin
ID, product
ID and date
. 只要在CMS中更改了
product
,就会在ws_shop_product-updated
插入一行,其中保留了admin
ID, product
ID和date
。
Some data: 一些数据:
product_id product_title
---------- -------------
1 iPhone 5
updated_product updated_admin updated_date
--------------- ------------- ------------
1 301 2013-04-13 00:00:00
1 302 2013-04-15 00:00:00
1 303 2013-04-16 00:00:00
Now my question is: How can I fetch products with latest update information? 现在我的问题是:如何获取具有最新更新信息的产品?
product_id product_title latest_admin_id latest_date
---------- ------------- --------------- -----------
1 iPhone 5 303 2013-04-16 00:00:00
You could use a query like this: 您可以使用如下查询:
SELECT
p.product_id,
p.product_title,
u.updated_admin latest_admin_id,
u.updated_date latest_date
FROM
`ws_shop_product-updated` u INNER JOIN ws_shop_product p
ON u.updated_product = p.product_id
WHERE
(u.updated_product, u.updated_date) IN
(SELECT updated_product, MAX(updated_date)
FROM `ws_shop_product-updated`
GROUP BY product_id)
Please see fiddle here . 请看这里的小提琴。
The subquery will return the maximum updated_date for each product, the outer query will return all columns of all rows that have the maximum updated_date for every product. 子查询将返回每个产品的最大updated_date,外部查询将返回所有行的每个产品的最大updated_date最大的所有列。
Because you are using mysql, you can use mysql's special (and non-portable) group by functionality to produce this fairly simple query: 因为您使用的是mysql,所以可以使用mysql的特殊(非便携式)按功能分组以产生以下相当简单的查询:
SELECT * FROM (
SELECT p.product_id, p.product_title,
u.updated_admin latest_admin_id, u.updated_date latest_date
FROM ws_shop_product p
LEFT JOIN `ws_shop_product-updated` u ON u.updated_product = p.product_id
ORDER BY u.updated_date DESC) x
GROUP BY 1
This query will return all products, even if they don't have a row in the "updated" table - returning null
values for the "latest" columns when there's no such row. 该查询将返回所有产品,即使它们在“ updated”表中没有一行也是如此-当没有此类行时,将为“ latest”列返回
null
值。
The reason this works is that (for mysql only) when not all non-aggregated columns are named in the group by, mysql returns the first row found for each unique combination of values of columns named in the group by clause. 起作用的原因是(仅对于mysql)当不是所有非聚合列都在group by中命名时,mysql返回在group by子句中命名的列的每个值的唯一组合中找到的第一行。 By ordering the data in the subquery latest-first, the first row found for each product_id will be the latest.
通过在子查询latest-first中对数据进行排序,为每个product_id找到的第一行将是最新的。
You can try this : 您可以尝试以下方法:
WITH CTE ( PRODUCTID, PRODUCT_TITLE ) AS ( SELECT * FROM dbo.ws_shop_product ), CTE2 ( updated_id, updated_product, updated_admin, updated_date, ROW ) AS ( SELECT * , ROW = ROW_NUMBER() OVER ( PARTITION BY UPDATED_PRODUCT ORDER BY UPDATED_DATE DESC ) FROM dbo.ws_shop_productupdated ) SELECT A.* , B.UPDATED_ADMIN , UPDATED_DATE FROM CTE A JOIN CTE2 B ON A.PRODUCTID = B.UPDATED_PRODUCT WHERE ROW = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.