【问题标题】:Sql querying Ids of a table inner joined with a 'list' tableSql查询与“列表”表连接的表的ID
【发布时间】:2018-11-15 21:45:33
【问题描述】:

在 Sqlite 中,我有以下表格:

CREATE TABLE "Person" (Id INTEGER PRIMARY KEY,
"Age" INTEGER, "Email" TEXT)

CREATE TABLE "_Person_Name" (Id INTEGER PRIMARY KEY,
Owner INTEGER NOT NULL, Name TEXT,
FOREIGN KEY(Owner) REFERENCES Person(Id))

其中第二个表代表一个人名的字符串列表。

我想通过匹配名称来查询 Person.Id,这样多个条件可能会在同一行中匹配在_Person_Name.Name 的不同行中。例如,假设 Person.Id 1 有 2 个关联的行 _Person_Name.Name "John" 和 "Smith",它们的 _Person_Name.Owner=1。然后我想要一个基于搜索“John”和“Smith”的查询,准确返回这个 Person.Id 1。不应返回“John Wilson”或“Jonas Smith”,但应返回“John Theodore Smith”。

我尝试了以下方法:

SELECT Person.Id FROM Person 
INNER JOIN _Person_Name ON Person.Id = _Person_Name.Owner 
WHERE (Name LIKE 'John') AND (Name LIKE 'Smith');

但这不起作用。它分别找到具有每个条件的人,但两者的合取似乎只适用于同一行,因此不返回任何内容。

如何同时搜索这两个条件,以使它们都适用于相同的人员 ID,但可以在列表的不同行中匹配?

编辑:这是一个带有数据的架构示例。这只是一个示例,用于处理任意模式和关联的“列表”表的自动化工具。

Table Person
Id    Age    Email
==================
1      30    john@test.com
2      28    lucie@gmail.com
3      47    bob@gmail.com

Table _Person_Names
Id     Name   Owner (Foreign Key references Person.Id)
1      John   1
2      C.     1
3      Smith  1
4      Lucie  2
5      Smith  2
6      Bob    3
7      Smith  3

查询应该只返回 ID 1,因为只有 Person.Id 1 在 _Person_Names 表中同时具有“John”和“Smith”。

【问题讨论】:

    标签: sql sqlite


    【解决方案1】:

    问题是查找_Person_Names 内是否有 2 行包含 Name 列中的值 JohnSmith 并且在列 Owner 中具有相同的值。
    这与Person 表无关。
    如果可以找到 2 个这样的行,则列 Owner 中的值是表 Person 中的 Id。正确的?
    检查此代码:

    SELECT Owner FROM 
    (SELECT pn.Owner AS Owner, pn.Name AS Name1, p.Name AS Name2 
    FROM _Person_Names AS pn 
    INNER JOIN _Person_Names AS p ON (pn.Owner = p.Owner) AND (Name1 <> Name2))
    WHERE (Name1 = 'John') AND (Name2 = 'Smith')
    

    【讨论】:

    • 我知道,但这根本不是我想要的。正如我所说,我希望每个名字都包含 John OR Smith,我只想获取名单中同时包含“John”和“Smith”行的人员的 ID。您的查询还返回“Lucie Smith”、“John F Kennedy”等。我只在寻找“John C. Smith”、“John Theodore Smith”、“Bob John Smith Wilcrow”等。 (如果您想知道,这是一个工具,它可以在转换为 Sqlite 后端的非 Sql 查询语言中处理任意用户定义模式中的任意列表。)
    • 这不起作用。名称的每个部分都位于表 _Person_Name 中其自己的行中的 Name 列中,其中 Owner 字段将表 Person 的 Person.Id 作为 Owner。
    • 你的意思是约翰和史密斯在不同的行?
    • 非常感谢您花时间回答。我不知道您可以将同一个表内部连接到自身,但是重命名它是有意义的。我会测试你的解决方案。
    • 当然您可以将一个表加入到自身中,这是一种非常常见的做法。
    【解决方案2】:

    由于名字、中间名和姓氏都在同一列中,您也可以尝试将 WHERE 子句修改为:

    WHERE Name LIKE 'John % Smith'
    

    与 forpas 和 Namandeep_Kaur 方法的结果相同,只是体积更小

    【讨论】:

    • 不,它们不在同一列 - 它们可能在,但不需要。我会尝试更新我的问题以使其更清楚。
    【解决方案3】:

    在 WHERE 子句中使用 AND 运算符不会检索到正确的结果。您应该使用 OR 运算符

    编辑部分从这里开始

    select Person.ID, Dusra_table.name
        from person, dusra_table
    where Person.ID = Dusra_Table.Owner
        and (Dusra_Table.Name = 'John'
                OR  Dusra_Table.Name = 'Smith'
          )
        and Person.ID = ANY(Select Dusra_Table.Owner from Dusra_table where Name = 'John');
    

    Dusra_Table 是 _Person_Names 表

    【讨论】:

    • 不是我要找的,请看我的其他评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多