如何根据一秒钟内存在的数据从mySQL数据库的一个表中选择一条记录?

如何根据一秒钟内存在的数据从mySQL数据库的一个表中选择一条记录?,mysql,syntax,Mysql,Syntax,请原谅我的无知。SQL无疑是我所受教育中最大的“差距”之一,我正在努力纠正这一差距,到了10月份。以下是场景: 数据库中有两个表,我需要从中访问某些数据。一个是用户,另一个是对话日志。基本结构概述如下: 用户: id(INT) 名称(TXT) 对话日志 userid(INT)//与users中的id相同的值-实际上是这个表中我要检查的唯一字段 输入(TXT) 响应(TXT) (注意,我只列出了与当前挑战{或可能}相关的字段的结构) 我要做的是从users表返回一个名称列表,该列表在con

请原谅我的无知。SQL无疑是我所受教育中最大的“差距”之一,我正在努力纠正这一差距,到了10月份。以下是场景:

数据库中有两个表,我需要从中访问某些数据。一个是
用户
,另一个是
对话日志
。基本结构概述如下:

用户:

  • id(INT)
  • 名称(TXT)
对话日志

  • userid(INT)//与users中的id相同的值-实际上是这个表中我要检查的唯一字段
  • 输入(TXT)
  • 响应(TXT)
(注意,我只列出了与当前挑战{或可能}相关的字段的结构)

我要做的是从users表返回一个名称列表,该列表在conversation_log表中至少有一条记录。目前,我使用两个单独的SQL语句来完成这项工作,其中一个语句检查对话日志中的记录,如果不是数千次的话,也会被调用数百次,每个用户id调用一次,只是为了查看该id是否存在记录

目前,这两条SQL语句如下:

users
中选择
id
,其中1;(获取下一个查询的用户ID值列表)

conversation\u log
中选择
id
,其中
userid
=$userid limit 1;(检查现有记录)

现在,我在用户表中列出了4000多个用户。我相信你可以想象这个方法需要多长时间。我知道有一种更简单、更有效的方法可以做到这一点,但是自学成才,这是我还没有学会的。任何帮助都将不胜感激。

诸如此类:

SELECT *
FROM users
WHERE EXISTS (
    SELECT *
    FROM conversation_log
    WHERE users.id = conversation_log.userid
)

用简单的英语:从
用户
中选择每一行,这样在
对话日志
中至少有一行具有匹配的
用户ID

您必须执行所谓的“加入”操作。这,嗯,根据两个表的共同值将它们的行连接在一起

看看这对你是否有意义:

SELECT DISTINCT users.name
FROM users JOIN conversation_log ON users.id = converation_log.userid
现在连接本身是一个“内部连接”,这意味着它只返回两个表共有的行。换句话说,如果某个特定的对话\ u log.userid不存在,它将不会返回该用户id的行、用户或对话日志的任何部分

另外,+1表示问题措辞清晰:)


编辑:我添加了一个“DISTINCT”,这意味着过滤掉所有的重复项。如果一个用户出现在多个对话日志行中,而您没有DISTINCT,那么您将多次获得该用户的名称。这是因为JOIN执行一个或多个表中与您的JOIN ON条件匹配的行的可能组合。

您需要阅读的是JOIN语法

SELECT count(*), users.name 
FROM users  left join conversion_log  on users.id = conversation_log.userid
Group by users.name
如果需要,可以在末尾添加
HAVING count(*)>0

您在哪里解决了“至少有一个会话日志”的要求,而不为具有多个会话日志的用户返回多个记录?如果您正在进行内部连接,并且没有与连接谓词匹配的会话日志(具有特定的用户id),则具有该id的用户不会出现。True,但是如果有多个日志,你会得到多个记录。这就是DISTINCT应该考虑的。@DaveMorton它总是让我惊讶的是,本质上相同的答案可以在StackOverflow上得到截然不同的分数。你有没有试过我的答案?或者ontangent'a就这一点而言?有效,但连接会更短,可能更好,这取决于优化器。@JimGarrison连接会提供多个“副本”或来自
用户的一行,其中有来自
对话日志的多个对应行。为了解决这个问题,您需要采用
分组方式
,但到那时,您的查询将比我提出的更加复杂。至于性能,一个“严肃”的DBMS应该不会有任何优化问题,但我不确定MySQL。你只需要在这里加入(而不是左加入)。您还指的是按用户分组.name
而不是按用户分组.id
,对吗?