我有一个看起来像这样的表:
id | age | date
----|-----|--------------------
1 | 18 | 2016-07-1 00:00:00
2 | 20 | 2016-07-1 00:00:00
3 | 20 | 2016-07-1 00:00:00
4 | 22 | 2016-08-1 00:00:00
5 | 22 | 2016-08-1 00:00:00
6 | 30 | 2016-08-1 00:00:00
7 | 25 | 2016-09-1 00:00:00
我需要获得每个月+年最常见的年龄。
到目前为止我有这个问题:
$ages = User::selectRaw('age, MONTH(date) as month, YEAR(date) as year, count(*) as count')
->groupBy(['age', 'month', 'year'])
->orderBy('year', 'asc')
->orderBy('month', 'asc')
->get();
这仅获得每个月+年的每个年龄的计数。我需要看起来像这样的东西:
[
{
"age": 20,
"month": 7,
"year": 2016,
},
{
"age": 22,
"month": 8,
"year": 2016,
},
{
"age": 25,
"month": 9,
"year": 2016,
}
]
即。对于7月(月== 7)2016年,有两个20和一个18,所以20是最常见的年龄。对于2016年8月,最常见的是22,依此类推......
对此有什么好的查询?感谢。
答案 0 :(得分:0)
select substr(max(concat(lpad(count,10,'0'),age)),11) as age, month, year
from (
select age, MONTH(date) as month, YEAR(date) as year, count(*) as count
from test6
group by age, MONTH(date), YEAR(date)
) A
group by month, year
order by year, month
substr(max(concat(lpad(count,10,'0'),age)),11)
汇编字符串“count-age”,获取最大值(最大计数行数(*)),并缩短“年龄”。
答案 1 :(得分:0)
试试这个
$ages = User::selectRaw('age, MONTH(date) as month, YEAR(date) as year, count(*) as count')
->groupBy(['age', 'month', 'year'])
->orderBy('year', 'asc')
->orderBy('month', 'asc')
->havingRaw('count = MAX(count)')
->get();
答案 2 :(得分:0)
这个操作在MySQL中有点困难。这有三个选择:
第三个看起来像这样:
select yyyy, mm,
substring_index(group_concat(age order by cnt desc), ',', 1) as mode
from (select age, year(date) as yyyy, month(date) as mm,
count(*) as cnt
from test6 t
group by age, MONTH(date), YEAR(date)
) t
group by yyyy, mm;
第一个看起来像这样:
select year(date), month(date), age
from test6 t
group by year(date), month(date)
having count(*) = (select count(*)
from test6 t2
where year(t2.date) = year(t.date) and
month(t2.date) = month(t.date)
group by age
order by count(*) desc
limit 1
);
请注意,这会返回与第一个查询稍有不同的结果。如果多个年龄段最常见,此版本将返回重复项。
答案 3 :(得分:0)
我不知道如何重新格式化,但在MySQL中,有效的查询可能如下所示:
SELECT a.*
FROM
( SELECT DATE_FORMAT(date,'%Y-%m') yearmonth
, age
, COUNT(*) total
FROM my_table
GROUP
BY yearmonth
, age
) a
JOIN
( SELECT yearmonth
, MAX(total) total
FROM
( SELECT DATE_FORMAT(date,'%Y-%m') yearmonth
, age
, COUNT(*) total
FROM my_table
GROUP
BY yearmonth
, age
) x
GROUP
BY yearmonth
) b
ON b.yearmonth = a.yearmonth
AND b.total = a.total;
如果两个年龄在给定月份的顶部并列,则此查询将返回两者。
如果允许“黑客”解决方案,这里有一个很好的......
SELECT yearmonth
, age
FROM
( SELECT DATE_FORMAT(date,'%Y-%m') yearmonth
, age
FROM my_table
GROUP
BY yearmonth
, age
ORDER
BY yearmonth
, COUNT(*) DESC
) x
GROUP
BY yearmonth;
对于绑定结果,此解决方案将以不确定的方式选择一个结果。根据文档,它也不能保证产生正确的结果。虽然在实践中它始终如此,但我更喜欢第一种解决方案。