我对MySQL或数据库一般都不熟悉,所以这里是我的数据模型(table {cols}]),以使我的问题连贯一致:
Domains{id, name}
注意:此处的“域名”不涉及网络域名
Subdomains{id, domain_id, name}
Items{id, subdomain_id, name}
SubdomainsItems{id, subdomain_id, item_id}
没有domain_id列!
我的Items Controller
有一个函数fetchWithin($domains, $subdomains)
,最终应该执行两个复杂的find()
之一。这是我无法解决的复杂问题。
以编程方式我可以做到这一点,但我确信更好的方法是通过聪明的连接等。唉,目前这是方法:
如果$domains
为空,请仅执行步骤2和3,否则:
foreach($domains as $d)
:获取Subdomains
的所有行Subdomain.domain_id
= Domains.id
为$subdomains
foreach($subdomains as $s)
:go SubdomainsItems
所有行SubdomainsItems.subdomain_id
= Subdomains.id
$item_ids
foreach($items_ids as $i)
:获取Items
所有行Items.id
= SubdomainsItems
。items_id
这是有效的,但我认为这可以避免关系数据库的强大功能,我想了解这个应该如何完成(即根据Cakephp约定或简单地通过任何MySQL)声明会实现这一点)。
非常感谢帮助,我尝试来学习SQL的更复杂的方面,但它恰好在我的脑海中。 :S
答案 0 :(得分:1)
使用问题中描述的结构,必要的查询形式为:
SELECT
*
FROM
items
LEFT JOIN
subdomains ON (
items.subdomain_id = subdomains.id
)
LEFT JOIN
domains ON (
subdomains.domain_id = domains.id
)
WHERE
domains.name = "foo"
AND
subdomains.name IN ('some', 'list', 'of', 'subdomains');
与问题中的逻辑相比,这将所有三个表连接在一起并允许按域名或子域名(或涉及任何或所有三个表的任何其他标准)查找所有项目;一般来说,如果你想在数据库中查找数据并使用多个查询来获取数据 - 那么有一种更有效的方法。
使用Cake创建此类查询的方法有很多种。最简单的可能是使用the join key并明确指定连接:
function fetchWithin($domains = null, $subdomains = null) {
$params = array(
'joins' => array(
array('table' => 'subdomains',
'alias' => 'Subdomain',
'type' => 'LEFT',
'conditions' => array(
'Subdomain.id = Item.subdomain_id',
)
),
array('table' => 'domains',
'alias' => 'Domain',
'type' => 'LEFT',
'conditions' => array(
'Domain.id = Subdomain.domain_id',
)
)
)
);
if ($domains) { // single value or an array
$params['conditions']['Domain.name'] = $domains;
}
if ($subdomains) { // single value or an array
$params['conditions']['Subdomain.name'] = $subdomains;
}
return $this->find('all', $params);
}