如何消除子查询来简化查询?
我有三台电话服务器将其扩展的状态定期推送到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应用程序一起工作。
任何想法?
加入它自己。要复制你说工作的查询结果,并给你你想要的结果:
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的值。
您是否尝试将订单添加到第二个视图?
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')
您可以在一个查询中组合GROUP BY和ORDER BY。
SELECT * FROM table GROUP BY extension ORDER BY extension, status
该查询还会返回无效数据,与由competent_tech提出的查询类似。在任何情况下,我都需要确定的答案。 – jjj916 2012-01-03 04:12:09
我认为,如果你只想要正确的答案,这包括你所描述的状态:假设一个未知扩展未知状态造成空,如果它创建一个空的
select systemid, extension, status from test where status='OK' or (status='UNKNOWN' and systemid is null);
字符串,相应地测试。
每个可能的分机将在表中出现三次 - 每个PBX一个。例如,此处的查询返回所有OK扩展,但不会检索扩展404。没有在任何地方注册的扩展可能是我需要显示的最重要的数据。 – jjj916 2012-01-03 04:08:27
您必须在其他列的条件上动态选择列。我认为这个查询将起作用。
Select
extension name,
status,
CASE
WHEN status ='OK' THEN systemid
ELSE NULL END
From table
ORDER BY status
GROUP BY extension
我没有执行它。请建议如果此查询存在任何问题。
这不希望在GROUP BY之前使用ORDER BY子句运行。当我颠倒两个人的顺序时,我得到无效的结果。 – jjj916 2012-01-03 16:16:27
为什么查询对于您的Web应用程序来说太复杂?无论如何,你是否可以将它封装在一个存储过程中并从你的应用程序调用它? – nycdan 2012-01-03 03:25:27
除非你确实需要,否则不要在MySQL中使用视图。查询优化器在处理它们时很糟糕,特别是一旦你开始加入它们。 – PlexQ 2012-01-03 03:28:55
您的查询不会保证输出。即使MySQL支持分析,它也需要派生表/内联视图。您的查询不是子查询... – 2012-01-03 03:33:47