无法在我的数据库上运行特定的SQL查询

时间:2019-05-03 09:05:19

标签: mysql sql database

我有一个聊天应用程序数据库。

CREATE TABLE Users (uid int PRIMARY KEY, name text, phone text );

CREATE TABLE Messages (recipient int REFERENCES Users(uid), sender int 
REFERENCES Users(uid), time timestamp NOT NULL, message text NOT NULL, 
PRIMARY KEY (recipient, sender, time));

http://www.sqlfiddle.com/#!9/bd36d1

我想为发送最多消息的5个用户中的每个用户定义该用户发送的消息的平均长度。

我写了以下查询:

SELECT avg(strlen(message))
FROM Messages
WHERE sender IN
                (SELECT *
                 FROM (SELECT sender, COUNT(sender) AS NumberOfMessages
                       FROM Messages
                       GROUP BY sender) AS MessagesPerSender
                 ORDER BY NumberOfMessages DESC
                 LIMIT 5)

首先,此查询正确吗?它给我想要的结果吗?问题是我根本无法运行它,原因是我得到了错误:

“此版本的MySQL尚不支持'LIMIT&IN / ALL / ANY / SOME子查询”

3 个答案:

答案 0 :(得分:2)

对于mysql而言,这可能不是正确的方法

select sender,avg(length(message)),count(*)
from   messages
group by sender
order by avg(length(message)) desc limit 5;

+--------+----------------------+----------+
| sender | avg(length(message)) | count(*) |
+--------+----------------------+----------+
|      1 |               9.0000 |        1 |
|      9 |               5.5000 |        2 |
|      2 |               5.0000 |        1 |
+--------+----------------------+----------+
3 rows in set (0.00 sec)

请注意,这可能无法以您想要的方式处理抽奖。

答案 1 :(得分:2)

您的代码中有2个错误:

  1. 首先,您不能在MYSQL中使用strlen。那是微软 SQL Server方言而是需要使用length

  2. 第二,在您使用的子查询中,您正在使用两列 而不是一个。这将导致查询失败,因为等于 运算符仅需等于一列中的值。

这是您的查询:

select u.name, avg(length(m.message)), count(*)
from Messages m
inner join Users u on m.sender = u.uid
group by u.name
order by avg(length(m.message)) desc limit 5;

由于我为您提供了发件人的姓名而不是其ID,所以我改进了P. Salmon的回答。

希望这会有所帮助:)

答案 2 :(得分:1)

要找出答案,我将DMBS从MySQL更改为支持内部限制的Postgres。您的查询语法正确,但strlen()函数除外,正确的语法是length()

但是,您的查询失败的原因很简单:您正在执行where sender in (subquery),尽管子查询返回两个字段。 in运算符仅适用于单个字段查询。而且,您的子查询由两个查询组成,可以简化为一个查询。以下查询适用于Postgres 9.6,并且应适用于具有内部限制支持的任何版本的MySQL:

SELECT avg(length(message))
FROM Messages
WHERE sender IN (
    SELECT sender
    FROM Messages
    GROUP BY sender
    ORDER BY COUNT(sender) DESC
    LIMIT 5
)

在您的样本数据上运行时,它会产生以下结果:

+----------+
|   avg    |
+----------+
|   6.25   |
+----------+

有效的SQL提琴(Postgres 9.6):http://www.sqlfiddle.com/#!17/bd36d/6/0