2013-12-24 121 views
0

我需要执行mysql查询以计算用户邮箱使用的空间。 消息线程可能由两方 (发件人/收件人)拥有多个邮件(回复,跟进),并标记有一个或多个标记(收件箱,发件等)。从几个表中获取不同的结果

必须满足以下条件:
a)用户是消息的收件人或作者;
b)消息由任何标签标记:1,2,3,4;
c)中不同的仅记录,即如果线程,包含消息标记有 4分的标签(例如图1和4的多于一个:收件箱和已发送)的计算 是在一个标签仅

完成

我曾尝试下面的查询,但我没能获得不同的值 - 该 主题/值复制:

SELECT SUM(LENGTH(subject)+LENGTH(body)) AS sum 
FROM om_msg_message omm 
JOIN om_msg_index omi ON omm.mid = omi.mid 
JOIN om_msg_tags_index omti ON omi.thread_id = omti.thread_id AND omti.uid = user_id 
WHERE (omi.recipient = user_id OR omi.author = user_id) AND omti.tag_id IN (1,2,3,4) 
GROUP BY omi.mid; 

表的结构:

  1. om_msg_message - 字段标题和正文都被计算

    +--------------+------------------+------+-----+---------+----------------+ 
    | Field  | Type    | Null | Key | Default | Extra   | 
    +--------------+------------------+------+-----+---------+----------------+ 
    | mid   | int(10) unsigned | NO | PRI | NULL | auto_increment | 
    | subject  | varchar(255)  | NO |  | NULL |    | 
    | body   | longtext   | NO |  | NULL |    | 
    | timestamp | int(10) unsigned | NO |  | NULL |    | 
    | reply_to_mid | int(10) unsigned | NO |  | 0  |    | 
    +--------------+------------------+------+-----+---------+----------------+ 
    
  2. om_msg_index

    +-----+-----------+-----------+--------+--------+---------+ 
    | mid | thread_id | recipient | author | is_new | deleted | 
    +-----+-----------+-----------+--------+--------+---------+ 
    | 1 |   1 |  1392 | 1211 |  0 |  0 | 
    | 2 |   1 |  1211 | 1392 |  1 |  0 | 
    +-----+-----------+-----------+--------+--------+---------+ 
    
  3. om_msg_tags_index

    +--------+------+-----------+ 
    | tag_id | uid | thread_id | 
    +--------+------+-----------+ 
    |  1 | 1211 |   1 | 
    |  4 | 1211 |   1 | 
    |  1 | 1392 |   1 | 
    |  4 | 1392 |   1 | 
    +--------+------+-----------+ 
    
+0

考虑提供适当的DDL和/或sqlfiddle连同SET – Strawberry

回答

0

这里的另一个解决方案:

SELECT SUM(LENGTH(omm.subject) + LENGTH(omm.body)) as totalLength 
FROM om_msg_message omm 
JOIN om_msg_index omi 
    ON omi.mid = omm.mid 
    AND (omi.recipient = user_id OR omi.author = user_id) 
JOIN (SELECT DISTINCT thread_id 
     FROM om_msg_tags_index 
     WHERE uid = user_id 
      AND tag_id IN (1, 2, 3, 4)) omti 
    ON omti.thread_id = omi.thread_id 

我假设:

  1. user_id是一个参数标记/主变量,被查询为单个用户。
  2. 您希望每个用户的所有消息的总数,而不是每个消息的总长度(这是您的版本中的GROUP BY子句获得的)。
  3. ,在这两种om_msg_messageom_msg_indexmid是独一无二的。
+0

它确实有用,非常感谢! – Oleg

0

所以,你的问题中的人条款。我不是MYSQL专家,但是在T-SQL中,您可以将其更改为在包含EXISTS的子查询上具有where子句,以便您的连接不会弹出两行。您需要补偿这样一个事实,即您有两行不同的tagID与主连接数据的每一行相关联。

我可以做到这一点的跨平台将与双向四左联接该链接的表则要求一个非空值1,2,3,或4相当低效的;我相信在MySQL中有更好的方法来实现它,但现在你知道问题是什么,你可能会知道一个更好的解决方案。

+0

庵所期望的结果,则'WHERE子句EXISTS'是SQL标准的一部分,并且很可能会比'LEFT JOIN's更有效。但是,您对这个问题的诊断是现成的。 –

+0

@Dylan感谢您的帮助!我使用Clockwork-Muse的解决方案,因为它确实为我解决了问题。 – Oleg

相关问题