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

Cakephp - Finding records with no associated records

好的,我有这个:

$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);

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

假设你们的关系是:

  • 线程有许多订阅
  • 订阅属于线程

您的 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 的目的)。然后只有 select 没有订阅的记录(在 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);