Mysql SQL-艰难构建一个;复杂的;要求

Mysql SQL-艰难构建一个;复杂的;要求,mysql,Mysql,我有三张桌子: 对话(包含私人对话) 对话成员-结构:convId | userId(包含参与对话的成员的所有ID,以便多人可以一起交谈。参与对话的一个用户等于一行) 用户(用户表,经典) 我想做的是: 用户有朋友。因此,浏览我的应用程序的用户可以从朋友的ID打开对话 因此,首先,我想在conversations members中查找是否只有用户Id和他的朋友Id之间存在对话,然后在conversations表中提取conversations members给我的对话Id 是否可以在一个请求

我有三张桌子:

  • 对话
    (包含私人对话)
  • 对话成员
    -结构:
    convId | userId
    (包含参与对话的成员的所有ID,以便多人可以一起交谈。参与对话的一个用户等于一行)
  • 用户
    (用户表,经典)
我想做的是:

用户有朋友。因此,浏览我的应用程序的用户可以从朋友的ID打开对话

因此,首先,我想在
conversations members
中查找是否只有用户Id和他的朋友Id之间存在对话,然后在
conversations
表中提取
conversations members
给我的对话Id

是否可以在一个请求中执行此操作?如果我必须执行两个请求,我甚至不知道如何构建第一个请求(
查找包含用户Id和朋友Id的行,它们具有相同的会话Id)


我的第一个想法是创建一个
conversations
表,该表还将以字符串形式包含成员Id,如“55105,85,22”,然后对其进行解析以获得一个数组,但我认为,如果我能够处理所需的SQL请求,我想这样做的方式会给我更多的选择,而且可能会更简单。

不建议使用具有多个值的列

当关系为1-N时,通常需要使用带有两个键的表,例如ConvID-UserID。您的索引是由这两列创建的,因为不允许生成重复项(例如,在同一个ConvID上生成两次UserID)

但是,作为对你问题的回答,是的,可以进行搜索。您需要在SQL表中搜索两个不同ID位于同一行的条目。您可以使用LIKE子句,但这不是一个好的选择(我认为这是最糟糕的WHERE子句)

语法如下所示:

SELECT convId FROM conversations-members WHERE userId LIKE '%id1%' AND userId LIKE '%id2%'

对于一些额外的建议,如果您的对话始终是一对人,请在“对话”表中使用两个新字段。如果您的对话可以有一到N个成员,请使用答案开头建议的“对话成员”

要查找仅涉及两个特定用户的对话,您可以执行以下操作

SELECT convId, COUNT(*)
  FROM `conversations-members`
 WHERE userId IN (FIRST_USER, SECOND_USER)
 GROUP BY convId
HAVING COUNT(*) = 2
HAVING
行过滤掉除您想要的两个用户之外的任何用户的对话

您可以将其用作子查询:

SELECT whatever
  FROM conversations
 WHERE convId IN (
          SELECT convId
            FROM `conversations-members`
           WHERE userId IN (FIRST_USER, SECOND_USER)
           GROUP BY convId
          HAVING COUNT(*) = 2
       )
如果希望与两个用户和任何其他用户进行对话,可以将子查询更改为
HAVING COUNT(*)>=2


专业提示:SQL使用连字符
-
平均减法。避免在列和表名中使用它们。

以字符串形式出现,如“55105,85,22”否,否,千次否。SQL列中以逗号分隔的值被认为是有害的。阅读有关规范化和非规范化的内容。可以。我远不是一个专业的开发人员,所以我在编码的同时学习。无论如何,我不是这样做的。你可以通过犯一些愚蠢的错误,比如去规范化你的数据,来成为一名专业的开发人员。别问我怎么知道的。:-)哈哈。我想这是你在自学的时候必须走的一条路:)@o-jones你复制了你的答案(xD)该死的后退按钮。谢谢。非常感谢你抽出时间。这正是我需要的!顺便说一句,我用下划线而不是连字符重命名了我的表:)命名表没有错
SELECT*FROM[INSERT].[INTO]
有效。使用保留字或算术字符命名表和列的唯一问题是必须记住将它们转义。在SQL server中,转义是
[]
。在MySql中,它是backticks。假设您的表中有500个用户。用户10和25是朋友。有一个conv是这样存储的:
1 | 100250
。您的查询将获取不需要的值。我认为我的帖子不够清晰,因为我没有使用具有多个值的列。我做了你在文章第一部分描述的事情。我解释说,使用一个包含多个值的列是我的第一个想法,但后来我决定使用另一个包含两列的表。不过,很高兴知道我可以使用LIKE操作符来发出具有多个值的请求。我没想到,thanks@cid,为了解决这个问题,它们需要存储始终以逗号开头和结尾的值(例如,如果逗号是值分隔符),然后使用类似的值,如:'%1','%1'。我只是试着解决这个问题,即使这是一个“糟糕”的做法。表上的结果大概是10,20500,但你们可以进行“精确”搜索。@SakuraKinomoto是的,这是一个解决办法,但正如你们在回答中所说的,这是一个糟糕的做法有时,你们还需要知道如何用糟糕的做法“节省”你们的时间。你想象不到我在一些SQL客户机上发现了什么。而且没有选择去修复它。解释如何处理格式不正确/存储不正确的数据是不错的,如果您正确声明,如果您能够创建自己的数据模型,您将永远不会这样做。