CakePHP HABTM 关系中的子查询 SQL
我想按标签推荐相关产品,并按最匹配的顺序排序。
产品和标签之间的 HABTM 模型关联
class Product extends AppModel {
//..
var $hasAndBelongsToMany = array("Tag");
//..
}
,反之亦然。连接表名称也是“products_tags”。
对于Ex.sample..
//just sample of Product contain Tag data
$products[0]['Tag'] = array('touch', 'phone', '3G', 'apple'); //iPhone
$products[1]['Tag'] = array('phone', '3G', 'BB'); //BB
$products[2]['Tag'] = array('touch', '3G', 'apple'); //iPad
$products[3]['Tag'] = array('3G', 'air card'); //3G air card
在此示例中,与iPhone最相关的优先级排序是..ipad
- (在3个标签中找到)
- BB(在2个标签中找到)
- aircard(仅1个匹配)
Cake如何使用模型find()来获取像这样的子查询:
SELECT DISTINCT (product_id) AS id, (
/* sub-query counting same tags*/
SELECT COUNT(*) FROM tags as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE product_id = id
AND Tag.name IN ( 'touch', 'phone', '3G', 'apple' )
) AS priority /*this is weight count by how many same tags*/
FROM `tags` as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE Tag.name
IN ( 'touch', 'phone', '3G', 'apple' )
ORDER BY priority DESC
上面的 SQL 查询返回的正是我所需要的。但我找不到解析 CakePHP 的 AppModel->find() 方法参数的方法。
I want to suggest related products by tags and sort order by the most matched.
the HABTM model association between Product and Tag
class Product extends AppModel {
//..
var $hasAndBelongsToMany = array("Tag");
//..
}
and vice versa in Tag model. also join-table name is "products_tags".
for Ex.sample..
//just sample of Product contain Tag data
$products[0]['Tag'] = array('touch', 'phone', '3G', 'apple'); //iPhone
$products[1]['Tag'] = array('phone', '3G', 'BB'); //BB
$products[2]['Tag'] = array('touch', '3G', 'apple'); //iPad
$products[3]['Tag'] = array('3G', 'air card'); //3G air card
in this sample the most related to iPhone sort by priority are..
- ipad (found in 3 tags)
- BB (found in 2 tags)
- aircard (only 1 matched)
How Cake's way using Model find() to get sub-query like this:
SELECT DISTINCT (product_id) AS id, (
/* sub-query counting same tags*/
SELECT COUNT(*) FROM tags as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE product_id = id
AND Tag.name IN ( 'touch', 'phone', '3G', 'apple' )
) AS priority /*this is weight count by how many same tags*/
FROM `tags` as Tag
LEFT JOIN products_tags AS ProductTag ON ( Tag.id = ProductTag.tag_id )
WHERE Tag.name
IN ( 'touch', 'phone', '3G', 'apple' )
ORDER BY priority DESC
SQL query above return exactly what I needed. but I can't find the way to parse params to CakePHP's AppModel->find() method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果这个sql的结果不使用分页(假设正常网页中的相关产品有3-5条)为什么不使用这个复杂的SQL呢?
即在您的产品模型中创建一个函数 relatedProducts()
然后使用 $this->query($sql)
示例代码将是:
然后您可以在控制器中使用它
If the result of this sql does not use pagination (assuming that related products in a normal webpage are 3-5 entries) why don't you use this complex SQL instead?
i.e. create a function relatedProducts() in your Product model
then use $this->query($sql)
sample code will be:
Then you can use it in the controller by