Mysql SQL:在一个字段中查找具有公共值的多个项的查询
我有一个数据库的结构如下:Mysql SQL:在一个字段中查找具有公共值的多个项的查询,mysql,sql,database,relational-database,Mysql,Sql,Database,Relational Database,我有一个数据库的结构如下: UserInfo ---------- Id (INT PK AI) UserId (INT) InfoTypeId (INT FK -> InfoType.Id) Value (varchar) InfoType ---------- Id (INT PK AI) InfoTypeName (VARCHAR) Id | UserId | InfoTypeId | Value -------------------------------- 1 | 1
UserInfo
----------
Id (INT PK AI)
UserId (INT)
InfoTypeId (INT FK -> InfoType.Id)
Value (varchar)
InfoType
----------
Id (INT PK AI)
InfoTypeName (VARCHAR)
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"
这些行表示给定用户的信息。例如,我可能在InfoType
表中有以下行:
Id | InfoTypeName
-----------------
1 | "First Name"
2 | "Last Name"
3 | "Age"
而UserInfo
中的行如下所示:
UserInfo
----------
Id (INT PK AI)
UserId (INT)
InfoTypeId (INT FK -> InfoType.Id)
Value (varchar)
InfoType
----------
Id (INT PK AI)
InfoTypeName (VARCHAR)
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表中引用名为“John”、姓为“Smith”的用户的所有行。这意味着我要删除第1、2、3、10、11和12行。我不知道如何编写查询
编辑:
我可以用
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 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"));
我明白了
您可以在此处使用
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';
我自己运行子查询
选择ui.UserId,max(case-when-it.TypeName='First-name'然后value-end)作为First\u-name,max(case-when-it.TypeName='Last-name'然后value-end)作为UserInfo-ui的Last\u-name在ui.InfoTypeId=it.rowid-group-by-ui.UserId上加入InfoType
并在所有4行中为First Name和Last Name生成空值。注意:我必须更改一些内容,因为我意识到我设置的测试数据库略有不同。我将列命名为“TypeName”而不是“InfoTypeName”,并使用sqlite,因此有一个隐式rowid@ewok . . . 你应该问一个新问题。这个问题被标记为MySQL,这是MySQL的正确答案。SQLite是完全不同的。好吧,很公平。虽然只有一条注释,但在姓氏
之后有一个多余的逗号。在启动MySql并在那里进行测试之后。它可以工作。接下来,这可以扩展到2个以上的字段吗?例如,如果我有一个中间名字段,并且我想删除所有“John David Smith”字段,该怎么办?