1

我想创建一个重用select语句结果的SQL语句(使用sqllite ..所以我不能使用函数、IF语句等)。这就是它目前的样子

INSERT INTO search_email(many_fields, threadid) VALUES ('many_fields',
    CASE 
    WHEN
            (
                (SELECT COUNT(tableX.threadid) %threadIDquery% 
                ) > 0
            )
    THEN

                (SELECT tableX.threadid %threadIDquery% LIMIT 1)

    ELSE 
            0
    END
)

我想重用第一次选择的结果,而不是必须制作另一个(几乎相同的)选择语句。

更新:对于那些想知道我要做什么的人..这是查询的完整版本:

INSERT INTO search_email(meta, subject, body, sender, tos, ccs, folder, threadid) VALUES ('meta1','subject1','body1','sender1', 'tos1',' ccs1','folder1',
    CASE 
    WHEN
            (
                (SELECT COUNT(search_email.threadID) FROM search_email 
                                                            WHERE search_email.subject MATCH '%query%'  AND 
                                                            (
                                                                (search_email.sender = '%sender' AND search_email.tos = '%receiver%')
                                                                OR 
                                                                (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                                                            )
                ) > 0
            )
    THEN

            (SELECT search_email.threadID FROM search_email 
                                                        WHERE search_email.subject MATCH '%query%'  AND 
                                                        (
                                                            (search_email.sender = '%sender%' AND search_email.tos = '%receiver%')
                                                            OR 
                                                            (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                                                        )  LIMIT 1
            )

    ELSE 
            //generate new thread ID
    END
)

基本上我试图找出是否已经存在接收电子邮件的电子邮件线程..所以我检查主题是否匹配,如果匹配,我检查电子邮件的发件人和收件人是否匹配(在任一方向) ..如果电子邮件线程存在,我只需插入相同的电子邮件线程ID,否则我生成一个新的线程ID

更新 2:只是为了澄清,我正在寻找一种方法来保存 sqllite 编译器,使其免于进行两次相同的搜索.. 而不是简单地节省打字(或使其更具可读性等)

更新 3:我想知道如果 threadID 是从 dbase 中检索到的,而不是生成的,此语句是否有办法返回生成的 threadID。你可以在这里找到答案

4

1 回答 1

3

这是构造查询的另一种方法:

INSERT INTO search_email(meta, subject, body, sender, tos, ccs, folder, threadid)
    SELECT 'meta1', 'subject1', 'body1', 'sender1', 'tos1', 'ccs1', 'folder1',
            coalesce((SELECT search_email.threadID
                      FROM search_email 
                      WHERE search_email.subject MATCH '%query%' AND 
                            ((search_email.sender = '%sender%' AND search_email.tos = '%receiver%') OR
                             (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                            )
                      LIMIT 1
                     ),
                     <generate new thread id here>
                    )

这是使用 aselect而不是values. 它获取与条件匹配的线程 id,如果不匹配,则为 NULL。的第二个子句coalesce在第一个为 NULL 时运行。您可以在那里生成新的 id。

我确实对这种方法有疑问。对我来说,您似乎应该有一个管理线程的线程表。ThreadId 应该是此表中的自动递增 id。然后 emails 表可以引用这个 id。换句话说,我认为需要更详细地考虑数据模型。

以下查询不会查询工作,但它提供了将线程移动到子查询的想法:

INSERT INTO search_email(meta, subject, body, sender, tos, ccs, folder, threadid)
    SELECT 'meta1', 'subject1', 'body1', 'sender1', 'tos1', 'ccs1', 'folder1',
            coalesce(t.threadID,
                     <generate new thread id here>
                    )
    from (SELECT search_email.threadID
          FROM search_email 
          WHERE search_email.subject MATCH '%query%' AND 
                ((search_email.sender = '%sender%' AND search_email.tos = '%receiver%') OR
                 (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                )
          LIMIT 1
         ) t

它不起作用的原因是该from子句将不返回任何行,而不是返回 1 行具有 NULL 值。所以,要得到你想要的,你可以使用:

    from (SELECT search_email.threadID
          FROM search_email 
          WHERE search_email.subject MATCH '%query%' AND 
                ((search_email.sender = '%sender%' AND search_email.tos = '%receiver%') OR
                 (search_email.sender = '%receiver%' AND search_email.tos = '%sender%')
                )
          union all
          select NULL
          order by (case when threadId is not null then 1 else 0 end) desc
          LIMIT 1
         ) t

这样可以确保在没有线程时返回 NULL 值。

于 2012-12-27T14:58:20.577 回答