Cakephp - 查找没有相关记录的记录

时间:2015-11-14 09:33:38

标签: cakephp inner-join

好的,我有这个:

$user_id = AuthComponent::user('id');
$joins = [
        ['table' => 'subscriptions',
            'alias' => 'Subscription',
            'type' => 'INNER',
            'conditions' => [
                'Subscription.thread_id = Thread.id',
                'Subscription.user_id = '.$user_id
            ]
        ]
    ];

    $unsubscribed = $this->Thread->find('all',[
        'contain' => [
            'Subscription' => ['conditions' => ['Subscription.user_id' => $user_id]]
        ],
        'joins' => $joins,
        'fields' => ['name','modified'],
        'limit' => 10
    ]);

    debug($unsubscribed);

它基本上找到所有具有附加到当前用户的订阅的线程。 我真正想要的是负面结果。或者换句话说:当前用户没有订阅的所有线程? 有没有办法让条件消极?或类似的东西?

1 个答案:

答案 0 :(得分:0)

假设你的关系是:

  • 主题有多个订阅
  • 订阅belongsTo Thread

您的SQL将是:

SELECT Thread.*
FROM threads AS Thread
LEFT JOIN subscriptions AS Subscription
  ON Thread.id = Subscription.thread_id
    AND Subscription.user_id = ##user_id##
WHERE Subscription.user_id IS NULL;

关键概念是你需要LEFT JOIN,而不是INNER JOIN。此SQL将所有线程连接到所有用户的订阅,并且不会消除那些没有订阅的线程行(即,LEFT JOIN的目的)。然后只选择没有订阅的记录(在WHERE子句中找到)

翻译成Cakephp:

$user_id = AuthComponent::user('id');
$joins = [
    ['table' => 'subscriptions',
        'alias' => 'Subscription',
        'type' => 'LEFT',
        'conditions' => [
            'Subscription.thread_id = Thread.id',
            'Subscription.user_id = '.$user_id
        ]
    ]
];

$unsubscribed = $this->Thread->find('all',[
    'conditions' => ['Subscription.user_id' => null],
    'joins' => $joins,
    'fields' => ['name','modified'],
    'limit' => 10
]);

debug($unsubscribed);