Sql 在联接查询中选择以给定部分结尾的行?

Sql 在联接查询中选择以给定部分结尾的行?,sql,sqlite,select,subquery,Sql,Sqlite,Select,Subquery,我正在尝试创建一个复杂的SQL查询,至少对我来说是这样,但我真的不知道从哪里开始 基本上,我有一个角色对象,每个角色可以由几个部分组成。例如: 字符表: 字符_零件表: 因此,我知道: Character 1 is made of parts 4, 9, 5 Character 2 is made of parts 2, 34, 43 Character 3 is made of parts 21, 16, 41, 43 现在我要做的是选择所有以指定部分结尾的字符 例如,如果我选择以16、41

我正在尝试创建一个复杂的SQL查询,至少对我来说是这样,但我真的不知道从哪里开始

基本上,我有一个角色对象,每个角色可以由几个部分组成。例如:

字符表:

字符_零件表:

因此,我知道:

Character 1 is made of parts 4, 9, 5
Character 2 is made of parts 2, 34, 43
Character 3 is made of parts 21, 16, 41, 43
现在我要做的是选择所有以指定部分结尾的字符

例如,如果我选择以16、41、43结尾的所有字符,我将得到字符3。如果我选择所有以43结尾的字符,我将得到字符3和4

我假设我需要用子查询构建一些查询,但不确定如何启动,或者是否可以完成。到目前为止,我只是选择所有包含所需零件ID的内容,然后以编程方式进行比较,但这太慢了,因为我选择的方式超出了需要


有什么建议吗?

查询可能是这样的

select * from character where id in (select character_id from character_parts where character_id = 'required no' AND character_id = 'required no' AND character_id = 'required no')
//required number is the part_id you want to specify.
添加另一列,从末尾算起,例如:

from_end | id | character_id | part_id
--------------------------------------
      2  | 1  | 1            | 4
      1  | 2  | 1            | 9
      0  | 3  | 1            | 5
      2  | 4  | 2            | 2
      1  | 5  | 2            | 34
      0  | 6  | 2            | 43
      3  | 7  | 3            | 21
      2  | 8  | 3            | 16
      1  | 9  | 3            | 41
      0  | 10 | 3            | 43
然后你可以做:

SELECT p0.character_id
  FROM character_parts AS p0
  JOIN character_parts AS p1 USING (character_id)
  JOIN character_parts AS p2 USING (character_id)
 WHERE p0.from_end = 0 AND p1.from_end = 1 AND p2.from_end = 2
   AND p0.part_id = 43 AND p1.part_id = 41 AND p2.part_id = 16
您可以尝试组_concat功能:

从character\u id=1的character\u parts中选择group\u concatpart\u id

查询应返回4,9,5

问题在于组_concat使用的顺序是任意的:

因此,假设您有一个定义零件顺序的字段位置,我们可以如下更新查询:

SELECT character_id, parts_concat FROM (
    SELECT character_id, group_concat(part_id) FROM (
        SELECT character_id, part_id FROM character_parts WHERE ORDER BY position ASC
    ) GROUP BY character_id
) parts
WHERE parts_concat LIKE '%,9,5'
从“从字符零件中选择零件id,其中字符id=1按位置排序ASC”中选择组零件id

查询现在将返回与定义的顺序完全相同的4,9,5部分

现在我们有了这个值,我们可以像搜索普通字符串一样搜索它。 如果我们想找到以某个字符串结尾的所有值,我们可以使用LIKE运算符

最后,查询如下所示:

SELECT character_id, parts_concat FROM (
    SELECT character_id, group_concat(part_id) FROM (
        SELECT character_id, part_id FROM character_parts WHERE ORDER BY position ASC
    ) GROUP BY character_id
) parts
WHERE parts_concat LIKE '%,9,5'
创建以下索引:

character_parts (part_id, character_id, id)
character_parts (character_id, id)

为了快速工作

在我看来,character\u parts表中有一个字段不够。我将添加一个字段,用于指定零件的顺序索引。换句话说,您如何确定16、41、43是后缀?您使用的是什么数据库服务器?21、16、41、43的顺序重要吗?如果是这样,您可能需要在零件表中添加某种order列。@mazzucci,很抱歉添加了SQLite标记。@heximal,事实上我现在也忘了添加一个ID列。零件的顺序很重要,它们按ID排序。
SELECT  c.character
FROM    character_parts cp
JOIN    character c
ON      c.id = cp.character_id
WHERE   cp.part_id = 43
        AND cp.id =
        (
        SELECT  id
        FROM    character_parts cpo
        WHERE   cpo.character_id = cp.character_id
        ORDER BY
                id DESC
        )
character_parts (part_id, character_id, id)
character_parts (character_id, id)