【问题标题】:SQL programming help.... using count and max ..etcSQL 编程帮助.. 使用 count 和 max ..etc
【发布时间】:2012-03-04 09:21:58
【问题描述】:

我有一系列表格:

  • TECH PERSONNEL (pplSoft, fname, lname, pittID, expertise, office phone) 其中 fname 是名字,lname 是姓氏。

  • USERS (pplSoft, fname, lname, pittID, office phone)

  • CATEGORIES (category id, category, description) 此表列出了所有可能提交的工单类别。

  • INVENTORY(machine name, IP, network port, MACADDR, location id)

  • LOCATIONS(location id, location, building, notes)

  • TICKETS (ticket number, owner pplSoft, date submitted, date closed, days worked on, category id, machine name, location, description)

  • ASSIGNMENT (ticket number, tech pplSoft, date assigned, status) 其中 statusheld 是一个枚举,可以是:assigned、in progress、delegate、close success 或 close unsuccessful。

我的任务是 列出设备名称所有具有最大数量的机器的名称 2011年12月和2012年1月两个月的问题。

我必须把它变成 SQL。

我可以这样做吗?

select machine_name 
from tickets 
where date_submitted >= '01-DEC-2012' and 'date_submitted <= '31-JAN-2012'  

但是我需要算票还是用max?

我如何从这里取得进展?

【问题讨论】:

  • 你能举个输入输出的例子来说明你想做什么吗?
  • 我想查找并列出在 12 月和 1 月内出现问题数量最多的所有设备(机器)的名称
  • 由于任何表中的列都不是“设备名称”,因此上述问题无法回答。优雅的变化最好留给英语课;在计算中,严格地用一个名字来称呼一个对象可以帮助每个人——包括你。想必,问题是根据机器打开的票数统计,2011 年 12 月和 2012 年 1 月哪个机器名称的问题最多?对吗?

标签: sql oracle database-design aggregate-functions sqlplus


【解决方案1】:

与任何复杂的 SQL 查询一样,秘诀是将其分解为多个部分,最好是独立测试的部分。

第一个问题是确定每台机器在相关期间的票数。这里的标准是什么?可能,如果一台机器的问题从 2011 年 11 月开始并延续到 2011 年 12 月,则应该计算在内;同样,如果一个问题在 2012 年 1 月开始但在 2012 年 2 月完成,则应该计算在内。所以,我们需要:

SELECT machine_name, COUNT(*) AS num_tickets
  FROM tickets
 WHERE date_completed >= '01-Dec-2011' AND date_submitted <= '31-Jan-2012'
 GROUP BY machine_name;

如果您决定只计算提交工单的日期,请将条件调整为引用date_submitted 两次;同样,如果仅计算票证完成的日期,则引用date_completed 两次。请注意,如果一台机器有一张 11 月开始的票,直到 2 月才解决,上面的查询将计算它;如果您使用任何一种替代方案,则该机器在相关期间没有问题。

这告诉我们在该时间段内机器有多少张票。现在我们需要找出最大的票数是多少:

SELECT MAX(num_tickets) AS max_tickets
  FROM (SELECT machine_name, COUNT(*) AS num_tickets
          FROM tickets
         WHERE date_completed >= '01-Dec-2011' AND date_submitted <= '31-Jan-2012'
         GROUP BY machine_name
       );

现在我们需要选择拥有此票数的机器名称:

SELECT machine_name
  FROM (SELECT MAX(num_tickets) AS max_tickets
          FROM (SELECT machine_name, COUNT(*) AS num_tickets
                  FROM tickets
                 WHERE date_completed >= '01-Dec-2011' AND date_submitted <= '31-Jan-2012'
                 GROUP BY machine_name
               )
        ) AS n
  JOIN (SELECT machine_name, COUNT(*) AS num_tickets
          FROM tickets
         WHERE date_completed >= '01-Dec-2011' AND date_submitted <= '31-Jan-2012'
         GROUP BY machine_name
       ) AS m
    ON n.max_tickets = m.num_tickets;

假设 Oracle 支持 WITH 子句,这可以简化(相当):

WITH t AS
    (SELECT machine_name, COUNT(*) AS num_tickets
       FROM tickets
      WHERE date_completed >= '01-Dec-2011' AND date_submitted <= '31-Jan-2012'
      GROUP BY machine_name
    )
SELECT t.machine_name
  FROM t
  JOIN (SELECT MAX(num_tickets) AS max_tickets FROM t) AS m
    ON t.num_tickets = m.max_tickets;

警告:我在子查询中使用了“AS 别名”,这是 SQL 标准所支持的。我相信 Oracle 不允许使用“AS 别名”,只需要在表名后使用“别名”;我不确定这是否也适用于子查询的名称。如果 'AS m' 和 'AS n' 符号引起问题,请尝试删除 AS。您可能会发现与列重命名“AS num_tickets”等类似的问题,但我相信 Oracle 在这种情况下确实允许 AS。

据推测,这只是一系列问题之一,因为答案似乎不需要任何表,除了门票表。想必,其他问题需要用到其他表格。

【讨论】:

    【解决方案2】:

    您需要使用group by。

    select machine_name, count(*) as numMachines
    from tickets
    where date_submitted >= '01-DEC-2011' and 'date_submitted <= '31-JAN-2012'
    group by machine_name
    order by numMachines desc
    

    【讨论】:

    • 非常感谢...但是这会占用最大数量的问题吗? (我猜你计算每台机器提交的票数对吗?并列出每台机器最多?)
    【解决方案3】:

    您的查询将为每个问题返回一行。您的第一步是按机器对结果进行分组,以便为​​每台机器获取一行。然后,您可以添加一个计数列,显示该机器存在多少问题。

    要找到最大数量的问题,您需要将查询放入子选择中,以便提取最大值。然后,您可以将其用作 having 子句中的子选择,以返回具有该最大计数的机器。

    SELECT machine_name, COUNT(machine_name) AS ticket_count
      FROM tickets
      WHERE date_submitted >= '01-DEC-2012' AND date_submitted <= '31-JAN-2012'
      GROUP BY machine_name
      HAVING ticket_count = (
        SELECT MAX(ticket_count) FROM (
          SELECT COUNT(machine_name) AS ticket_count
            FROM tickets
            WHERE date_submitted >= '01-DEC-2012' AND date_submitted <= '31-JAN-2012'
            GROUP BY machine_name
        )
      )
    

    【讨论】:

      【解决方案4】:
      select machine_name, count(machine_name) as totalTicketCount
      from tickets 
      where date_submitted >= '01-DEC-2012' and 'date_submitted <= '31-JAN-2012' 
      Group By machine_name
      Order by totalTicketCount DESC 
      

      【讨论】:

      • 你需要一个 group by 子句@Maarten
      • @Naval:我太快了。谢谢你指出我这个错误。
      猜你喜欢
      • 2014-05-26
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多