SQL:查询在一个字段中查找具有共同值的多个项目

SQL: Query to find multiple items with a common value in one field

我有一个结构如下的数据库:

UserInfo
----------
Id (INT PK AI)
UserId (INT)
InfoTypeId (INT FK -> InfoType.Id)
Value (varchar)

InfoType
----------
Id (INT PK AI)
InfoTypeName (VARCHAR)

这些行代表给定用户的信息。例如,我可能在 InfoType table 中有以下行:

Id | InfoTypeName
-----------------
1  | "First Name"
2  | "Last Name"
3  | "Age"

UserInfo 中的行如下:

Id | UserId | InfoTypeId | Value
--------------------------------
1  | 1      | 1          | "John"
2  | 1      | 2          | "Smith"
3  | 1      | 3          | "20"
4  | 2      | 1          | "John"
5  | 2      | 2          | "Doe"
6  | 2      | 3          | "30"
7  | 3      | 1          | "Jane"
8  | 3      | 2          | "Doe"
9  | 3      | 3          | "25"
10 | 4      | 1          | "John"
11 | 4      | 2          | "Smith"
12 | 4      | 3          | "25"

我想创建一个查询,从 UserInfo table 中删除所有引用名字为“John”而姓氏为“Smith”的用户的行。这意味着我要删除第 1、2、3、10、11 和 12 行。我不知道如何编写查询。

编辑:

我能够通过

获得用户 ID 列表
SELECT DISTINCT ui1.UserId 
FROM UserInfo ui1
    INNER JOIN UserInfo ui2 
    ON ui1.UserId = ui2.UserId
WHERE (ui1.InfoTypeId = 1 AND ui1.Value = "John" AND ui2.InfoTypeId = 2 AND ui2.Value = "Smith");

此外,要删除的行列表

SELECT * FROM UserInfo ui WHERE ui.UserId IN
    (SELECT DISTINCT ui1.UserId 
    FROM UserInfo ui1
        INNER JOIN UserInfo ui2 
        ON ui1.UserId = ui2.UserId
    WHERE (ui1.InfoTypeId = 1 AND ui1.Value = "John" AND ui2.InfoTypeId = 2 AND ui2.Value = "Smith"));

但是当我用 DELETE 替换 SELECT 时:

DELETE FROM UserInfo WHERE UserId IN
    (SELECT DISTINCT ui1.UserId 
    FROM UserInfo ui1
        INNER JOIN UserInfo ui2 
        ON ui1.UserId = ui2.UserId
    WHERE (ui1.InfoTypeId = 1 AND ui1.Value = "John" AND ui2.InfoTypeId = 2 AND ui2.Value = "Smith"));

我明白了

SQL Error [1093] [HY000]: You can't specify target table 'UserInfo' for update in FROM clause

你可以在这里使用join

delete ui
    from UserInfo ui join
         (select ui.UserId,
                 max(case when it.InfoTypeName = 'First name' then value end) as first_name,
                 max(case when it.InfoTypeName = 'Last name' then value end) as last_name
          from UserInfo ui join
               InfoType it
               on ui.InfoTypeId = it.id
          group by ui.UserId
         ) uu
         using (UserId)
    where uu.first_name = 'John' and uu.last_name = 'Smith';