在CakePHP 3中,假设我要删除所有部门,其中员工已命名为" John" (部门有很多员工,员工属于部门)
最简单的方法是过滤所有这些部门,并在foreach循环中逐个删除它们:
$departments = $this->Departments->find()
->matching('Employees', function ($q) {
return $q->where(['Employees.name' => 'John']);
})
->all();
foreach ($departments as $department) {
$this->Departments->delete($department);
}
这将导致一个SELECT查询加上每个记录的一个DELETE查询。我更喜欢只有一个查询由数据库发送和执行。像这样:
DELETE Departments
FROM departments Departments
INNER JOIN employees Employees ON
Employees.department_id = Departments.id
AND Employees.name = 'John';
阅读文档我找到三种删除记录的方法:
使用CakePHP 3和ORM是否有一种优雅的方式来获取我的查询?
答案 0 :(得分:0)
deleteAll只是一个环绕
$this->Departments->query()
->delete()
->where([...])
->execute();
所以尽管如此,以类似的方式,我们可以这样做:
$departments = $this->Departments->query()
->delete()
->matching('Employees', function ($q) {
return $q->where(['Employees.name' => 'John']);
})
->execute();
但在这种情况下,您会注意到匹配条件被忽略。我看到有一个关于那个
的开放ticket如果您只想使用两个查询,则可以执行查询以检索所有ID并在第二个查询中删除所有ID:
$departments_ids = $this->Departments->find()
->select(['id'])
->matching('Employees', function ($q) {
return $q->where(['Employees.name' => 'John']);
})
->toArray();
$this->Departments->deleteAll(['id' => $departments_ids ]);
导致类似:
DELETE FROM departments WHERE id IN
(
// id list here
)
另一个解决方案可能是在子查询中转换内连接。实际上,您希望删除几乎所有名为John的员工的部门。
$employees = $this->Departments->Employees->find()
->select(['department_id'])
->distinct()
->where(['Employees.name' => 'John']);
$departments = $this->Departments->query()
->delete()
->where(['id IN' => $employees])
->execute();
答案 1 :(得分:0)
两件事:
第一:我建议的情况不正确
我的实际情况要复杂得多,所以我用众所周知的员工部门案例做了一个例子。我犯了一个错误:我需要的是删除属于某个部门的所有员工。我想从相关表上的基于表的con条件中删除数据。
实际上,你不能删除有一个名叫约翰的员工的部门,因为部门不是空的,那就是约翰! :d
这样的事情:
-- Create structures
CREATE TABLE IF NOT EXISTS departments (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
CREATE TABLE IF NOT EXISTS employees (
id int(11) NOT NULL AUTO_INCREMENT,
department_id int(11) NOT NULL,
name varchar(45) NOT NULL,
PRIMARY KEY (id),
KEY fk_employees_department_idx (department_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
ALTER TABLE employees
ADD CONSTRAINT fk_employees_departments FOREIGN KEY (department_id) REFERENCES departments (id) ON DELETE NO ACTION ON UPDATE NO ACTION;
-- Populate some data
INSERT INTO departments (id, name) VALUES
(1, 'Sales'),
(2, 'TI'),
(3, 'HHRR');
INSERT INTO employees (id, department_id, name) VALUES
(1, 1, 'John'),
(2, 1, 'Mary'),
(3, 2, 'Mark'),
(4, 3, 'Lorenzo');
-- Delete all employees that belong to the TI department (Mark should be removed)
DELETE emp FROM employees emp
INNER JOIN departments dep ON emp.department_id = dep.id AND dep.name = 'TI';
第二:您可以轻松地在CakePHP中执行此操作
您可以获得与上一个查询相同的结果:
$departments = $this->Employees->Departments->find()
->select(['Departments.id'])
->where(['Departments.name' => 'TI']);
$this->Employees->deleteAll(['Employees.department_id IN' => $departments]);
生成的mysql查询将是:
DELETE FROM employees WHERE department_id in
(SELECT Departments.id AS `Departments__id`
FROM departments Departments
WHERE Departments.name = 'TI')
......这是正确的,而且易于理解。 @arilia,你用第一个答案指出了这个方向。对不起,请小心。