简体   繁体   English

如何消除子查询以简化查询?

[英]How can I eliminate the subquery to simplify my query?

I have three phone servers pushing the status of their extensions into MySQL on a regular basis. 我有三台电话服务器,定期将其扩展状态推送到MySQL。 These systems are duplicates of each other in different geographic regions, but with the ability to fail over as needed. 这些系统在不同的地理区域中彼此相同,但是具有根据需要进行故障转移的能力。 Therefore they will report the same extensions but only one of the three systems will show the extension is registered ("OK") at any one time. 因此,他们将报告相同的分机,但是三个系统中只有一个会显示该分机在任何时间都已注册(“确定”)。

For example, table is as follows: 例如,表如下:

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

So extension 101 is registered to PBX01, 202 to PBX02, 303 to PBX03, and 404 is not registered to any PBX. 因此,分机101被注册到PBX01,202被注册到PBX02,303被注册到PBX03,而404未注册到任何PBX。 No extension can be registered to more than one PBX at a time. 一次分机不能注册到一个以上的PBX。

An OK status would be the "best" status and therefore the one I would wish to report, provided it exists. 正常状态将是“最佳”状态,因此,如果存在的话,我希望报告该状态。 However if there is an extension such as 404 that is not registered to any PBX I need to report that fact too. 但是,如果存在未向任何PBX注册的扩展名(例如404),我也需要报告该事实。

My desired output: 我想要的输出:

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

I have come up with the following query which delivers the result I want: 我想出了以下查询,可提供所需的结果:

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

However this query is too complex for my web application. 但是,此查询对于我的Web应用程序来说太复杂了。 I wish to create a view with the results of this query, however I cannot create a view with a subquery in the FROM clause. 我希望使用此查询的结果创建视图,但是无法在FROM子句中使用子查询创建视图。

I tried creating two views: one containing the subquery: 我尝试创建两个视图:一个包含子查询:

SELECT * FROM table ORDER BY extension,status

and a second view containing: 第二个视图包含:

SELECT * FROM view1 GROUP BY extension

However the results are invalid as they seem to ignore the ORDER BY in view1. 但是结果无效,因为它们似乎忽略了view1中的ORDER BY。

I also looked into a stored procedure however that doesn't work with my web application either. 我还研究了一个存储过程,但是该存储过程也不适用于我的Web应用程序。

Any ideas? 有任何想法吗?

Have you tried adding the order by to the second view? 您是否尝试过将订单添加到第二个视图?

SELECT * FROM view1 GROUP BY extension ORDER BY extension

Here's another more complex option that I know will work in SQL Server, but am unsure about in mysql. 我知道这是另一个更复杂的选项,可以在SQL Server中使用,但是不确定在mysql中。 This one fetches the OK extensions and then those extensions with no PBX (this is accomplished by selecting any extension that has a count of 3 to match the number of your extensions): 这将获取OK扩展名,然后获取那些没有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

If that syntax doesn't work in MySql or is too reliant on each extension being registered for each pbx and there being a total of 3 pbxs, the second select statement could be rewritten as: 如果该语法在MySql中不起作用或过于依赖于为每个pbx注册的每个扩展,并且总共3个pbx,则第二个select语句可以重写为:

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

or: 要么:

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

I think if you only want the correct answers, this covers the states you've described: 我认为,如果您只想要正确的答案,则可以涵盖您所描述的状态:

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

assuming that an unknown condition for an unknown extension creates null, if it creates an empty string, test accordingly. 假设未知扩展名的未知条件会创建null,如果创建空字符串,请进行相应测试。

You have to select column dynamically on condition on other column. 您必须根据其他列的条件动态选择列。 I think this query will work. 我认为此查询将起作用。

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

I havn't executed it. 我没有执行。 Please suggest if any problems are present with this query. 请建议此查询是否存在任何问题。

Join it to itself. 加入自己。 To replicate the results of the query that you said worked and gave you your desired results: 要复制您认为有效的查询结果并提供所需的结果,请执行以下操作:

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

I did not create the query above based on the desired output you provided, because the systemid column in the output you posted didn't have a value for extension 404. 由于您发布的输出中的systemid列没有扩展名404的值,因此我并未根据您提供的所需输出创建上述查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM