MYSQL组合多个子查询的结果

时间:2011-03-15 04:46:24

标签: mysql

我需要结合以下查询的结果。我需要将内部和外部处理的总消息放在一起。让我解释一下查询及其数据

示例数据:

+---------------------+---------------------+----------------+---------------+----------------+
| deviceCustomString2 | destinationUserName | deviceHostName | deviceProduct | sourceUserName |
+---------------------+---------------------+----------------+---------------+----------------+
| <FD54>              | test@dmroot.net     | gemslab385mb   | Test Server   | Exchange       |
| <FX54>              | test@dmroot.net     | gemslabcht     | Test Server   | Exchange       |
| <FZ54>              | test2@yahoo.com     | gemslab385mb   | Test Server   | External       |
| <FA54>              | test@dmroot.net     | gemslab385mb   | Test Server   | Exchange       |
| <FD54>              | test@dmroot.net     | gemslab385mb   | Test Server   | Exchange       |
+---------------------+---------------------+----------------+---------------+----------------+

查询1:

SELECT 
LEFT((LOWER(SUBSTRING_INDEX(b.deviceHostName,'.',1))),(LENGTH(SUBSTRING_INDEX(b.deviceHostName,'.',1))-2)) as "Device_Group",
COUNT(b.deviceCustomString2) as "Total_Messages_Processed_EXTERNAL"
FROM 
      ( SELECT                    
                   TEST2.deviceCustomString2,
                   TEST2.deviceHostName
         FROM
                   TEST2
         WHERE
                   TEST2.deviceProduct="Test Server"
         AND 
                   (TEST2.destinationUserName NOT LIKE '%dmroot.net%' 
                AND TEST2.destinationUserName NOT LIKE '%banco2%'
                AND TEST2.sourceUserName NOT LIKE '%Exchange%')
         GROUP BY
                   TEST2.deviceCustomString2,
                    TEST2.deviceHostName
                  ) as b

查询1结果:

+--------------+-----------------------------------+
| Device_Group | Total_Messages_Processed_EXTERNAL |
+--------------+-----------------------------------+
| gemslab385   |                                 1 |
+--------------+-----------------------------------+

QUERY2:

SELECT 
LEFT((LOWER(SUBSTRING_INDEX(a.deviceHostName,'.',1))),(LENGTH(SUBSTRING_INDEX(a.deviceHostName,'.',1))-2)) as "Device_Group",
    COUNT(a.deviceCustomString2) as "Total_Messages_Processed_INTERNAL"
FROM 
      ( SELECT                    
                   TEST2.deviceCustomString2,
                   TEST2.deviceHostName
         FROM
                   TEST2
         WHERE
                   TEST2.deviceProduct="Test Server"
     AND 
                   (
                    TEST2.destinationUserName LIKE '%dmroot.net%' 
                OR TEST2.sourceUserName  LIKE '%Exchange%'
               )
         GROUP BY
                   TEST2.deviceCustomString2


                  ) as a

GROUP BY
Device_group

查询2结果:

+--------------+-----------------------------------+
| Device_Group | Total_Messages_Processed_INTERNAL |
+--------------+-----------------------------------+
| gemslab385   |                                 2 |
| gemslabc     |                                 1 |
+--------------+-----------------------------------+

两个查询的结果都很好,它会删除重复的记录。

现在当我在2个查询之间添加UNION ALL时,我得到了这个结果

+--------------+-----------------------------------+
| Device_Group | Total_Messages_Processed_EXTERNAL |
+--------------+-----------------------------------+
| gemslab385   |                                 1 |
| gemslab385   |                                 2 |
| gemslabc     |                                 1 |
+--------------+-----------------------------------+

总计是正确的,但不显示TOTAL_MESSAGES_PROCESSED_INTERNAL。我如何使其输出如下:

+--------------+-----------------------------------+-----------------------------------+
| Device_Group | Total_Messages_Processed_INTERNAL | Total_Messages_Processed_EXTERNAL | 
+--------------+-----------------------------------+-----------------------------------+
| gemslab385   |                                 2 |                                 1 |
| gemslabc     |                                 1 |                                   | 
+--------------+-----------------------------------+-----------------------------------+

提前感谢您的帮助。

马塞罗

2 个答案:

答案 0 :(得分:1)

在内部选择中准备列表,在外部选择中有条件地计数组。

SELECT

  LEFT(LOWER(t.deviceGroup), LENGTH(t.deviceGroup) - 2) AS "Device_Group",

  COUNT(DISTINCT
    CASE
      WHEN t.destinationUserName NOT LIKE '%dmroot.net%' AND
           t.destinationUserName NOT LIKE '%banco2%' AND
           t.sourceUserName NOT LIKE '%Exchange%'
      THEN CONCAT(t.deviceCustomString2, '.', t.deviceHostName)
    END) AS "Total_Messages_Processed_EXTERNAL",

  COUNT(DISTINCT
    CASE
      WHEN t.destinationUserName LIKE '%dmroot.net%' OR
           t.sourceUserName LIKE '%Exchange%'
      THEN CONCAT(t.deviceCustomString2, '.', t.deviceHostName)
    END) AS "Total_Messages_Processed_INTERNAL"

FROM (
  SELECT
    deviceCustomString2,
    deviceHostName,
    SUBSTRING_INDEX(a.deviceHostName, '.', 1) AS deviceGroup,
    destinationUserName,
    sourceUserName
  FROM TEST2
  WHERE deviceProduct="Test Server"
) AS t

GROUP BY Device_Group

计算群组时,我正在使用此构造:CONCAT(t.deviceCustomString2, '.', t.deviceHostName)。您可以更好地了解自己的数据,因此表达式可以简单地更改为t.deviceCustomString2t.deviceHostName,只需关注DISTINCT关键字。

此外,为了略微帮助计算,我将SUBSTRING_INDEX(a.deviceHostName, '.', 1)移动到内部SELECT,因此它不会评估两次。

答案 1 :(得分:0)

你想要的并不是一个真正的联盟,它只是一个普通的联盟。这是一个例子,但我没有测试语法,所以在它工作之前可能需要一些调整:

(SELECT 
LEFT((LOWER(SUBSTRING_INDEX(b.deviceHostName,'.',1))),(LENGTH(SUBSTRING_INDEX(b.deviceHostName,'.',1))-2)) as "Device_Group",
COUNT(b.deviceCustomString2) as "Total_Messages_Processed_EXTERNAL", COUNT(a.deviceCustomString2) as "Total_Messages_Processed_INTERNAL"
FROM 
      ( SELECT                    
                   TEST2.deviceCustomString2,
                   TEST2.deviceHostName
         FROM
                   TEST2
         WHERE
                   TEST2.deviceProduct="Test Server"
         AND 
                   (TEST2.destinationUserName NOT LIKE '%dmroot.net%' 
                AND TEST2.destinationUserName NOT LIKE '%banco2%'
                AND TEST2.sourceUserName NOT LIKE '%Exchange%')
         GROUP BY
                   TEST2.deviceCustomString2,
                    TEST2.deviceHostName
                  ) as b LEFT JOIN 
      ( SELECT                    
                   TEST2.deviceCustomString2,
                   TEST2.deviceHostName
         FROM
                   TEST2
         WHERE
                   TEST2.deviceProduct="Test Server"
     AND 
                   (
                    TEST2.destinationUserName LIKE '%dmroot.net%' 
                OR TEST2.sourceUserName  LIKE '%Exchange%'
               )
         GROUP BY
                   TEST2.deviceCustomString2


                  ) as a ON a.deviceCustomString2 = b.deviceCustomString2 AND a.deviceHostName = b.deviceHostName

GROUP BY
Device_group