4

所以我昨天遇到了一个问题/问题。
我正在建立一个聊天(使用 AJAX)并使用两个表:

TABLE users -> 'name', 'username', 'password', 'time'
TABLE messages -> 'sendFrom', 'sendTo', 'message', 'time'

所以现在的示例消息是
'foo' | 'bar' | 'Hey, how are you?' | 130611134427611

我被告知正确的方法是使用一个ID列,并将其用作主键而不是用户名(无论如何,这是有道理的)。

好的,所以现在看起来像
TABLE users -> 'ID', 'name', 'username', 'password', 'time'
TABLE messages -> 'sendFrom', 'sendTo', 'message', 'time'

所以现在的示例消息是
'22' | '7' | 'Hey, how are you?' | 130611134427611

我已经设法对JOIN两个表返回第一个示例消息中的行,但是由于我也在检测用户按键,所以我需要扫描表两次,所以:

SELECT * 
FROM (SELECT * 
      FROM (SELECT * 
            FROM messages 
            WHERE sendTo = '$username'
              AND time > (SELECT time FROM users 
                          WHERE username = '$username' LIMIT 1)
              AND message <> '$keypressCode' 
            ORDER BY time DESC LIMIT 30) 
      ORDER BY time ASC) 
UNION
SELECT * 
FROM (SELECT * 
      FROM messages 
      WHERE message = '$keypressCode'
        AND time > (SELECT time FROM users 
                    WHERE username = '$username' LIMIT 1)
        AND sendTo = '$username' LIMIT 1);

但是现在,当然,我不只是从消息中选择;相反,我使用了一个长查询,例如

SELECT * FROM (
    SELECT u1.ID as sendTo, u2.ID as sendFrom, messages.message, .....
    .....
    .....
    .....
    .....
) as messages;

必须插入的位置messages(我还没有尝试过,但我认为是那样的。看,事情是我 DuckDuckGo'ed 和谷歌搜索但一无所获,所以我来到这里)


我的第一个问题是:有没有办法使用ALIAS表格messages,所以我不必扫描它两次?因此,相反,我只是将上述查询保存ALIAS为一个名为的表messages,并从中选择数据两次,在UNION.

此外,第一个问题的答案也将是一个答案:有没有一种方法可以ALIAS用来保存time从表中选择的内容?(因为,我再次搜索它两次)。


在实践中,我所做的可能不是低效的(因为最多会有 20 个用户),但是如果呢?另外,我是一名数学家,不管你喜不喜欢,我都非常担心效率!

非常感谢你,我希望我说清楚了。

4

3 回答 3

2

我不确定,但它看起来好像你想要一个视图

像这样定义该查询:

CREATE VIEW MyMessageView
AS
SELECT ...
FROM ...
...

现在,您可以在可以使用普通表的任何上下文中使用该视图:在 FROM 子句中、在 JOIN 子句中、作为子查询等:

SELECT  ...
FROM MyMessageView
WHERE ...
...
UNION
SELECT ...
FROM MyMessageView
WHERE ...
于 2013-06-20T19:12:06.687 回答
0

我正在回答我自己的问题,因为我认为人们可能正在寻找的是VIEW

首先,像这样定义该查询:

CREATE VIEW MyViewTable
AS
    SELECT ...
    FROM ...
    ...
...;

现在,您可以在可以使用普通表的任何上下文中使用该视图(这是一个单独的查询):在 FROM 子句中、在 JOIN 子句中、作为子查询等:

SELECT  ...
FROM MyViewTable
    WHERE ...
    ...

UNION

SELECT ...
    FROM MyViewTable
    WHERE ...

但有一些限制:

  • 不能 SELECT从您的视图中使用子查询,例如

     SELECT * FROM MyViewTable WHERE someColumn = (SELECT ... ...)
    

    但是(正常情况下)您可以VIEW在主查询中创建 and 时使用子查询。

  • SELECT 语句不能引用准备好的语句参数。
  • 该定义不能引用 TEMPORARY 表,并且您不能创建 TEMPORARY 视图。

(还有更多,但在我看来,这是最常见的查询之一,因此限制可能是最常见的错误之一。有关更多信息,请参阅SQLite 参考。)。

于 2013-06-21T14:24:35.653 回答
0

不要使用 UNION,而是在条件中放置一个 OR:

SELECT * 
    FROM messages 
    WHERE time > (SELECT time FROM users 
                  WHERE username = '$username' LIMIT 1)
        AND (message <> '$keypressCode' AND sendTo = '$username'
             OR message = '$keypressCode')
于 2013-06-20T09:32:52.587 回答