【问题标题】:Oracle sql count() function?Oracle sql count() 函数?
【发布时间】:2011-12-17 10:00:22
【问题描述】:

我对函数 count() 有疑问。我希望它只在特定条件下计算。

我要做的是显示每个公司,公司名称,公司老板的名字以及2010年超过三天的租金。

所以条件是:2010年超过三天的出租次数。

因此,如果公司没有任何满足条件的租金,则不应将其从结果表中消除,而应将其写入零。例如:

company 1 -------------------- BOSS 1-----------------------2
company 2---------------------- BOSS 2---------------------- 0 --doesn't satisfy the condition: 0 rentals
company 3-----------------------BOSS 3 ----------------------5
company 4---------------------- BOSS 4--------------------------1
company 4 ----------------------BOSS 5 ----------------------- 0 --doesn't satisfy the condition: 0 rentals

AND NOT

company 1----------------------BOSS 1---------------------------2
company 3--------------------- BOSS 3---------------------------5
company 4----------------------BOSS 4 --------------------------1

我的 sql 代码显示第二个表而不是第一个表。这是我的代码:

SELECT ag.nom_agence as NOM_AGENCE, ag.responsable_agence, count(*) as RESPONSABLE
FROM agences ag, locations l
WHERE ag.id_agence = l.id_agence AND
      l.date_location BETWEEN to_date('01/01/2010','DD.MM.YYYY') AND to_date('31/12/2010','DD.MM.YYYY') AND
      l.duree > 3
      group by ag.nom_agence,ag.responsable_agence

我想要这种格式的东西(没有 where 子句):

count(l.date_location BETWEEN to_date('01/01/2010','DD.MM.YYYY') AND to_date('31/12/2010','DD.MM.YYYY') AND
          l.duree > 3)

有什么想法吗?谢谢。

【问题讨论】:

    标签: sql oracle count conditional-statements


    【解决方案1】:

    您需要对位置表使用外连接,以确保始终拉入该期间内的所有租金,无论其长度如何。

    然后计算出租次数> 3天。

    试试这个:

    SELECT 
      NOM_AGENCE, 
      RESP_AGENCE,
      SUM(RESPONSABLE)
    FROM 
      (
        SELECT 
          ag.nom_agence as NOM_AGENCE, 
          ag.responsable_agence RESP_AGENCE, 
          CASE  
            WHEN l.duree > 3 THEN 1
            ELSE 0
          END RESPONSABLE
        FROM 
          agences ag LEFT OUTER JOIN locations l ON ag.id_agence = l.id_agence 
                                                 AND l.date_location 
                                                 BETWEEN to_date('01/01/2010','DD.MM.YYYY') 
                                                 AND to_date('31/12/2010','DD.MM.YYYY') 
      ) 
    GROUP BY 
      NOM_AGENCE,
      RESP_AGENCE
    

    【讨论】:

    • l.duree > 3 没有过滤掉它。实际上我需要它来满足条件the number of rentals exceeding three days。但是WHERE 子句限制了结果
    • 试试我最新的编辑,现在应该可以工作了 - 我对原始查询有点困惑
    • 它并没有真正起作用(error:missing keyword),但它让我了解了如何使用case
    • 抱歉,剪切和粘贴错误,我在else 0 之后留下了一个不应该存在的计数(*)。它现在可以工作了吗?
    • group by 子句有问题。 agences ag 定义在括号中,因此 ag.nom_agenceag.nom_responsble 未定义
    【解决方案2】:

    使用have子句:

    having count(*) > 0
    

    【讨论】:

      【解决方案3】:

      我的快速回答是你必须做 LEFT JOIN 而不是你做的 INNER JOIN。试试这个:

      SELECT ag.nom_agence as NOM_AGENCE, ag.responsable_agence, count(*) as RESPONSABLE
      FROM agences ag
      left join locations l on l.id_agence = ag.id_agence
      WHERE 
        l.date_location BETWEEN to_date('01/01/2010','DD.MM.YYYY') AND                                                                       
      
        to_date('31/12/2010','DD.MM.YYYY') AND
                 l.duree > 3
      group by ag.nom_agence,ag.responsable_agence
      

      【讨论】:

      • 同样的问题。 WHERE 子句限制了结果。它给了我与the inner join 相同的表
      【解决方案4】:
      SELECT ag.nom_agence as NOM_AGENCE, ag.responsable_agence, count(*) as RESPONSABLE
      FROM agences ag LEFT OUTER JOIN locations l ON ag.id_agence = l.id_agence 
      WHERE l.date_location BETWEEN to_date('01/01/2010','DD.MM.YYYY') AND to_date('31/12/2010','DD.MM.YYYY') AND l.duree > 3 
      group by ag.nom_agence,ag.responsable_agence 
      

      关键是您需要执行 LEFT OUTER JOIN,它将从您的代理表中检索所有记录,无论位置中是否有任何匹配记录

      【讨论】:

      • 同样的问题。 WHERE 子句限制了结果。它给了我与the inner join 相同的表
      【解决方案5】:

      试试下面的(我没试过)。

      它基本上是代理表和根据您的搜索过滤器按代理分组的租金之间的外部连接。

      NVL 将在正确查询中不匹配的机构的计数转换为 0。

      select left.id_agence, left.nom_agence, left.responsable_agence, NVL(right.count, 0)
      from
      (select id_agence, nom_agence, responsable_agence from agences) left
      left outer join 
      (
        SELECT id_agence, count(*) as count
        FROM locations
        WHERE date_location BETWEEN to_date('01/01/2010','DD.MM.YYYY') AND     to_date('31/12/2010','DD.MM.YYYY') AND
            duree > 3
        group by id_agence
      ) right
      on left.id_agence = right.id_agence
      

      【讨论】:

      • 它有效,但我不明白NVL 子句。对我来说似乎很先进,哈哈。我刚开始学习Oracle sql。不过谢谢:)
      • @mkab,如果值为空,NVL 只需将一个值替换为另一个值。例如,NVL(3, 4) 将返回 3,因为 3 不为空,但 NVL(NULL, 12) 将返回 12。由于外连接在数据集值不匹配的情况下产生空值,因此 NVL 允许我们将它们视为0.
      【解决方案6】:

      我找到了查询。它给了我正确的桌子

      SELECT ag.nom_agence as NOM_AGENCE, ag.responsable_agence as RESPONSABLE, count(case when to_char(l.date_location, 'YYYY') = '2010' and l.duree>3 then 1 end) as NOMBRE
      FROM agences ag, locations l
      WHERE ag.id_agence = l.id_agence
            group by nom_agence, responsable_agence
      

      感谢大家的帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        相关资源
        最近更新 更多