CakePHP HABTM 关系中的子查询 SQL

发布于 2024-09-12 18:07:25 字数 1286 浏览 8 评论 0原文

我想按标签推荐相关产品,并按最匹配的顺序排序。

产品和标签之间的 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

  1. (在3个标签中找到)
  2. BB(在2个标签中找到)
  3. 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..

  1. ipad (found in 3 tags)
  2. BB (found in 2 tags)
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怀念你的温柔 2024-09-19 18:07:26

如果这个sql的结果不使用分页(假设正常网页中的相关产品有3-5条)为什么不使用这个复杂的SQL呢?

即在您的产品模型中创建一个函数 relatedProducts()

然后使用 $this->query($sql)

示例代码将是:

class Product extends AppModel {
  //..
  var $hasAndBelongsToMany = array("Tag");
  //..
  function relatedProducts($parameters){
    $sql = "select..... where ....$parameters...";
    return $this->query($sql);
  }
}

然后您可以在控制器中使用它

$this->Product->relatedProducts($some_parameters);

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:

class Product extends AppModel {
  //..
  var $hasAndBelongsToMany = array("Tag");
  //..
  function relatedProducts($parameters){
    $sql = "select..... where ....$parameters...";
    return $this->query($sql);
  }
}

Then you can use it in the controller by

$this->Product->relatedProducts($some_parameters);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文