2012-12-27 134 views
1

我想创建一个SQL语句(使用sqllite ..所以我不能使用函数,IF语句等),它重用select语句的结果.. this就是它目前看起来像在CASE语句中重用SELECT语句的结果sqllite

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 
) 

我想要重用结果的第一选择具有再拍(几乎相同)select语句来代替。

更新:对于那些想知道什么,我试图做的。这里是查询的完整版本:

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:我在想,如果有此语句返回生成的线程ID的方式当且仅当该线程ID是从质数据库检索,而不是生成的..你可以找到答案here

+0

这是试图做什么?我可以看到你的答案如何解析数据,但我不认为它实际上正在做你所需要的。 –

+0

更新的问题,以解决您的意见 – abbood

+0

它是SQL Server或SQLite?您知道,即使您设法将查询的键入保存两次,查询也会运行两次,并产生可能不同的结果,对吧? –

回答

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> 
        ) 

这是使用一个select而不是values。它获取匹配条件的线程ID,如果没有匹配,则获得NULL。​​3210的第二个子句在第一个为NULL时运行。你可以在那里生成新的ID。

我确实有这个方法的问题。对我来说,你应该有一个管理线程的Thread表。 ThreadId应该是此表中的自动增量ID。电子邮件表然后可以引用这个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值。

+0

*叹* *我知道你的意思.. [理想情况下](http://www.jwz。org/doc/threading.html)我根本不会使用数据库来解决这个问题(例如电子邮件线程)。当客户有一个他们聪明的东西,当他们继续缩短开发时间时,会发生这种情况..虽然谢谢! – abbood

+0

oright它的工作原理!正确的答案授予.. +1 b/c你看起来像一个好人 – abbood

+0

后续问题:有没有办法让这个sql语句只返回threadID只有当它从表中提取..而不是生成? – abbood