2012-01-03 77 views
0

我有三台电话服务器将其扩展的状态定期推送到MySQL中。这些系统在不同地理区域彼此重复,但具有根据需要进行故障切换的能力。因此,他们将报告相同的扩展名,但三个系统中只有一个会显示该扩展程序在任何时候都被注册(“OK”)。如何消除子查询来简化查询?

例如,表如下:

+----------------+---------+----------+ 
| extension name | status | systemid | 
+----------------+---------+----------+ 
| 101   | OK  | PBX01 | 
| 101   | UNKNOWN | PBX02 | 
| 101   | UNKNOWN | PBX03 | 
| 202   | UNKNOWN | PBX01 | 
| 202   | OK  | PBX02 | 
| 202   | UNKNOWN | PBX03 | 
| 303   | UNKNOWN | PBX01 | 
| 303   | UNKNOWN | PBX02 | 
| 303   | OK  | PBX03 | 
| 404   | UNKNOWN | PBX01 | 
| 404   | UNKNOWN | PBX02 | 
| 404   | UNKNOWN | PBX03 | 
+----------------+---------+----------+ 

所以伸出部101被注册到PBX01,202至PBX02,303〜PBX03,和404没有被注册到任何PBX。一次不能将分机注册到多个集团电话。

确定状态将是“最佳”状态,因此我希望报告,如果它存在。但是,如果有一个扩展名(如404)未注册到任何PBX,我也需要报告该事实。

我想要的输出:

+----------------+---------+----------+ 
| extension name | status | systemid | 
+----------------+---------+----------+ 
| 101   | OK  | PBX01 | 
| 202   | OK  | PBX02 | 
| 303   | OK  | PBX03 | 
| 404   | UNKNOWN |   | 
+----------------+---------+----------+ 

我想出了以下查询它提供我想要的结果:

SELECT * FROM 
    (SELECT * FROM table 
    ORDER BY extension,status) AS dummytable 
    GROUP BY extension 

但是这个查询是针对我的web应用程序太复杂。我希望用这个查询的结果创建一个视图,但是我不能在FROM子句中用子查询创建一个视图。

我试图创建两个视图:包含子查询之一:

SELECT * FROM table ORDER BY extension,status 

和包含第二视图:

SELECT * FROM view1 GROUP BY extension 

然而结果是无效的,因为它们似乎忽略了ORDER BY在厂景。

我也研究了一个存储过程,但是它不能与我的web应用程序一起工作。

任何想法?

+0

为什么查询对于您的Web应用程序来说太复杂?无论如何,你是否可以将它封装在一个存储过程中并从你的应用程序调用它? – nycdan 2012-01-03 03:25:27

+0

除非你确实需要,否则不要在MySQL中使用视图。查询优化器在处理它们时很糟糕,特别是一旦你开始加入它们。 – PlexQ 2012-01-03 03:28:55

+0

您的查询不会保证输出。即使MySQL支持分析,它也需要派生表/内联视图。您的查询不是子查询... – 2012-01-03 03:33:47

回答

0

加入它自己。要复制你说工作的查询结果,并给你你想要的结果:

SELECT DISTINCT t1.extension 
    , IFNULL(t2.status, t1.status) AS status 
    , IFNULL(t2.systemid, t1.systemid) AS systemid 
FROM pbx AS t1 
    LEFT OUTER JOIN 
    pbx AS t2 
    ON t1.extension = t2.extension 
     AND t2.status = 'OK' 
GROUP BY t1.extension, t2.status 
ORDER BY t1.extension 

我没有创建上面根据您提供所需的输出查询,因为在输出systemid列你贴没没有扩展名404的值。

+0

此查询似乎完美工作,并提供相同(正确)的结果,我有。它比较慢(对于这个查询约为2.05秒,对我而言为0.008秒),但它为我的直接需求完成了工作。非常感谢你。 – jjj916 2012-01-03 16:24:05

+0

@ jjj916,是的,这是一个有点期待的结果..加入可能有时是昂贵的性能方面......但为了避免使用任何形式的子查询,这是我能想到的..我希望它可以以某种方式管理。 。 – Nonym 2012-01-03 16:29:06

0

您是否尝试将订单添加到第二个视图?

SELECT * FROM view1 GROUP BY extension ORDER BY extension 

下面是另一个更复杂的选项,我知道将在SQL Server中工作,但我不确定在mysql中。这一个获取确定的扩展,然后将这些扩展没有PBX(这是通过选择具有计数3,以配合您的分机数量的任何扩展实现):

SELECT ExtensionName , 
     STATUS , 
     PBX 
    FROM TABLE 
WHERE STATUS = 'OK' 

UNION 

SELECT ExtensionName , 
     'UNKNOWN' , 
     '' 
    FROM TABLE 
WHERE STATUS = 'UNKNOWN' 
GROUP BY ExtensionName 
HAVING COUNT(1) = 3 

ORDER BY ExtensionName 

如果语法不起作用在MySQL或是被注册为每个PBX每个延伸过于依赖并且存在被共3点的PBX,所述第二选择语句可以被重写为:

SELECT ExtensionName , 
     'Unknown' , 
     '' 
    FROM [TABLE] 
WHERE STATUS = 'UNKNOWN' 
    AND NOT EXISTS(SELECT 1 
        FROM TABLE t1 
        WHERE t1.ExtensionName = ExtensionName 
        AND STATUS = 'OK') 

或:

SELECT ExtensionName , 
     'Unknown' , 
     '' 
    FROM TABLE 
WHERE STATUS = 'UNKNOWN' 
    AND ExtensionName NOT IN (SELECT ExtensionName 
           FROM TABLE 
           WHERE STATUS = 'OK') 
+0

此查询返回无效数据,因为如果给定的扩展名存在,我总是在寻找合适的答案。此查询似乎返回任意结果。 – jjj916 2012-01-03 04:10:11

+0

你有一个包含PBX列表的单独表格吗? – 2012-01-03 04:14:32

+0

我不清楚选择'未知'会起作用。每个分机将始终在表中附加一个PBX。我所需的输出显示未注册行404旁边的空白PBX,但可轻松由应用程序逻辑处理。如果有帮助,我可以创建一个带有三个PBX列表的小表。 – jjj916 2012-01-03 04:39:13

0

您可以在一个查询中组合GROUP BY和ORDER BY。

SELECT * FROM table GROUP BY extension ORDER BY extension, status 
+0

该查询还会返回无效数据,与由competent_tech提出的查询类似。在任何情况下,我都需要确定的答案。 – jjj916 2012-01-03 04:12:09

0

我认为,如果你只想要正确的答案,这包括你所描述的状态:假设一个未知扩展未知状态造成空,如果它创建一个空的

select systemid, extension, status from test where status='OK' or (status='UNKNOWN' and systemid is null); 

字符串,相应地测试。

+0

每个可能的分机将在表中出现三次 - 每个PBX一个。例如,此处的查询返回所有OK扩展,但不会检索扩展404。没有在任何地方注册的扩展可能是我需要显示的最重要的数据。 – jjj916 2012-01-03 04:08:27

0

您必须在其他列的条件上动态选择列。我认为这个查询将起作用。

Select 
    extension name, 
    status, 
    CASE 
     WHEN status ='OK' THEN systemid 
     ELSE NULL END 
From table 
ORDER BY status 
GROUP BY extension 

我没有执行它。请建议如果此查询存在任何问题。

+0

这不希望在GROUP BY之前使用ORDER BY子句运行。当我颠倒两个人的顺序时,我得到无效的结果。 – jjj916 2012-01-03 16:16:27