【问题标题】:SQL WHERE IF clause issueSQL WHERE IF 子句问题
【发布时间】:2014-07-02 14:41:20
【问题描述】:

我有一个 SQL/Java 代码问题。基本覆盖如下:带有表的 MySQL 数据库。在此表中有多个列。一列由名称组成。关联的列是月。在第三列有计数。所以一个示例表将是

john - january - 5
john - january - 6 
mary - january - 5
Alex - February- 5
John - February - 6
John - February - 4
Mary - February - 3
John - march - 4

表格持续到 5 月。

所以约翰在五个月后出现,玛丽在 3 个月后出现,亚历克斯在 1 个月后出现。目前,我的 SQL 查询有点像这样。

    select name, sum(count)/4 
    from table where (category ='something' 
    AND month not like 'May') group by name;

基本上,这个查询应该做的只是显示每个名字和每月的平均计数。因此,总和将除以四(因为我排除了 May,所以它必须除以 Jan-April/4)。但是,问题是有些名字只出现在一个月(或两三个月)内。

这意味着对于该名称,计数的总和将仅除以该特定数字,以获得月份的平均计数。我该怎么办?我觉得这似乎需要在 where 子句中使用一些 if 语句。有点像如果不同的计数(因为月份可能重复​​)是某个数字,然后将总和(计数)除以每个名称的该数字?

另外,我认为这可能不是 where if 子句问题。我读过一些论坛,可能会用到一些案例?

【问题讨论】:

  • 是mysql还是sql-server?
  • "a mysql database" 我相信它只是标记错误。
  • Mysql 数据库。我很抱歉我搞砸了标签。我对此很陌生,不确定一切如何运作。如果我在其他地方搞砸了,请告诉我。我希望将来能够以最好的方式寻求帮助。
  • 你考虑过使用AVG()函数吗?
  • 如果我理解正确的话,对于每个名字 N 你想要 SUM(count) / M 其中 M 是实际上对名字 N 有计数的月数?

标签: mysql


【解决方案1】:

如果您需要每月平均,您可以按名称和月份分组并使用 AVG 功能:

SELECT `name`, `month`, avg(`count`)
FROM table 
WHERE `category` ='something' AND `month` NOT LIKE 'May'
GROUP BY `name`, `month`;

如果您需要所有期间的平均值,只需 GROUP BY 名称和 AVG 计数:

SELECT `name`, avg(`count`)
FROM table 
WHERE `category` ='something' AND `month` NOT LIKE 'May' 
GROUP BY `name`;

还有一个选择,如果你不喜欢AVG

SELECT `name`, sum(`count`)/(SELECT count(*) FROM `table` AS `t2` WHERE `category` ='something' AND `month` NOT LIKE 'May' and `t1`.`name` = `t2`.`name`) 
FROM `table` AS `t1` 
WHERE `category` ='something' AND `month` NOT LIKE 'May')
GROUP BY name;

但我会留在AVG

实际上,我更喜欢使用!= 而不是NOT LIKE 它提高了可读性

【讨论】:

  • 我会使用平均函数。但我的问题是这个。同一月份的数据库中可以有许多记录。一月可以出现十五次,二月十次,依此类推。出于我的目的,我需要每月的平均计数。如果我使用 avg 函数,它不会得到记录数的平均值吗?
  • 如果不是这样,它仍然会在实际出现的月数内获得平均值吗?就像alex出现在一个月内,所以他的平均值应该就是那个值,因为它应该除以1。玛丽应该被三除。约翰四点(因为只从 1 月到 4 月)。
  • @user3794422 不,它只会按组中元素的数量而不是总数来划分。所以你可以使用它(或者至少测试一下,看看它是否有效)
  • 非常感谢您。是的,我对此进行了测试。这是我在质疑它的优点之前应该做的。它就像一个魅力。如果已经问过这个问题,我向论坛道歉。虽然我找不到任何重复项。再次感谢 Uriil 和所有回复的人。阿明,也谢谢你。我很感激。
  • 不知道什么是子查询。因此,如果它看起来像“矫枉过正”,我无法真正发表评论。我不想麻烦你问为什么这很糟糕,除非你有时间。 :) 感谢所有帮助。
【解决方案2】:

为了完整起见,这里是WORKING FIDDLE。使用 AVG 函数是可行的方法,因为它将计算每个人每月的平均值。看看一月份的约翰.. 当计数(一月份)为 5 和 6 时,他的结果是 5.5.. 平均值 = 5.5。

SELECT 
  person, 
  month, 
  avg(counter)
FROM testing 
where 
(
  category ='something' 
  AND month <> 'May'
) 
GROUP BY person, month;

如果您想以您帖子中的方式查看数据,那么您可以执行此操作。 ANOTHER FIDDLE

SELECT
    person,
    group_concat(month),
    group_concat(average_count)
FROM(
    SELECT 
      person, 
      month, 
      avg(counter) as average_count
    FROM testing 
    where 
    (
      category ='something' 
      AND month <> 'May'
    ) 
    GROUP BY person, month
      ) as t
group by person;

【讨论】:

    【解决方案3】:

    试试这个:

    SELECT name, SUM(count) / COUNT(DISTINCT month)
    FROM table
    WHERE month != 'May'
    AND category = 'something'
    GROUP BY name
    

    【讨论】:

    • 这个也可以。它生成与 Uriils 相同的结果。他的第二个代码实际上和这个一样吗?这很奇怪,因为他说整个时期都会如此。无论哪种方式都有效...
    • 他的第二个查询不可能与此相同。请阅读我的 cmets 关于他的回答。
    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多