0

我目前正在网站上使用 PHP 和 SQL。有一个包含用户(帐户)、组织和关系表的数据库,用于将组织链接到帐户(多对多关系)

当我从数据库中删除一个帐户时,如果要删除的帐户是唯一链接到某个组织的帐户,SQL 查询还应该删除该帐户链接到的所有组织。

我对 SQL 比较陌生,并且已经构建了一个查询,该查询应该在上述条件下从组织表中删除一个组织。这是我的查询:

'DELETE FROM TBL_ORGANISATIONS WHERE id = (
    SELECT org_id FROM TBL_AFFILIATIONS WHERE account_email = :email AND (
        SELECT COUNT(*) FROM TBL_AFFILIATIONS WHERE org_id IN (
            SELECT org_id FROM TBL_AFFILIATIONS WHERE account_email = :email
        )
    ) = 1
)'

这是构建此查询的正确方法还是有更清晰/更有效的方法来做到这一点?正如我之前提到的,我对 SQL 还很陌生,还没有掌握所有 SQL 关键字的概念,这些关键字可用于构造诸如此类的查询(JOIN 等)

我提前感谢大家提供的任何建议。

顺便说一句:我正在使用 PDO,因此 :email 对于那些想知道的人来说。

4

3 回答 3

0

如果你有外键约束,就像我认为你应该的那样,那么这个语句将失败,因为从属记录仍然指向要删除的组织记录。

您可以使用ON DELETE CASCADE删除组织,就像 Mihai 在他的(现已删除)评论中建议的那样,但要做到这一点,您仍然需要检查是否只有一个附属机构与该组织相关联。

在这种情况下,我宁愿先查询组织的 ID。无论如何,您可能会手头有这些,因为您会知道要删除的帐户的详细信息。然后首先删除帐户,然后根据需要删除组织,使用如下所示的语句:

DELETE FROM TBL_ORGANISATIONS o
WHERE 
  o.id = :ThatIdYouQueriedBefore AND
  NOT EXISTS (SELECT 'x' FROM TBL_AFFILIATIONS a.org_id = o.id);

就我个人而言,我不是级联删除的忠实拥护者,因为一个看似很小的错误可能会花费您大量数据,但即使您确实使用它们,我也不认为它会使这种特殊情况变得更容易。

于 2013-10-29T20:26:45.437 回答
0

我想我会做两个逻辑查询。如果您需要保证删除总是一起发生,请随意包装事务,如果没有,则回滚。

首先,使用单个查询删除帐户和与组织从属关系的帐户(这里我假设您的帐户表名)

DELETE tbl_account,tbl_affiliations
FROM tbl_account INNER JOIN tbl_affiliations
   ON tbl_account.account_email = tbl_affiliations.account_email /* I am assuming join condition here, perhaps there is an id to be used instead */
WHERE tbl_account.acount_email = ?

然后,删除所有孤立的组织:

DELETE tbl_organizations
FROM tbl_organizations LEFT JOIN tbl_affiliations
  ON tbl_organizations.org_id = tbl_affiliations.org_id
WHERE tbl_affiliations.org_id IS NULL

请注意,由于最后一个查询不依赖于任何特定于帐户的信息,如果您不需要与帐户删除同步进行组织删除,您还可以考虑运行异步进程来清理孤立的组织。

这种方法的好处是,您可以始终以相同的方式删除用户帐户,使用第一个查询,因为无论是否有多个帐户与组织关联,这都有效。因此,您不需要任何额外的应用程序逻辑或 SQL SELECT 子查询来查找与组织关联的单个帐户的情况。

于 2013-10-29T20:31:53.163 回答
0

当您尝试一次从两个表中删除数据时,您可以试试这个。

DELETE from TBL_ORGANISATIONS TO JOIN TBL_AFFILIATIONS TA 
    ON(TO.id=TA.org_id) where TA.account_email=:email;

在这里,我们尝试使用 TO(即 id)和外键 TA(即 org_id)的主键从两个表 TBL_ORGANISATIONS 和 TBL_AFFILIATIONS 中删除行,并使用 where 子句 where TA.account_email=:email 添加条件。

于 2013-10-29T20:38:41.090 回答