我有一张投票表: id 是投票的人,投票 = 1是他参与的事实, num 是投票数。
我想从同一个查询中选择两个变量,而一个WHERE
条件只适用于一个变量。使用GROUP BY
和YEAR()
,这两个变量应该是MONTH()
相同的日期。
这是初始表的一个示例:
+----+------------+------+-----+
| id | date | vote | num |
+----+------------+------+-----+
| 1 | 2018-01-25 | 1 | 1 |
| 3 | 2018-01-25 | 1 | 1 |
| 4 | 2018-01-25 | 1 | 1 |
| 5 | 2018-01-25 | 1 | 1 |
| 1 | 2018-01-25 | 1 | 1 |
| 3 | 2018-01-25 | 1 | 1 |
| 4 | 2018-01-25 | 1 | 1 |
| 1 | 2017-12-25 | 1 | 2 |
| 2 | 2017-12-25 | 1 | 2 |
| 5 | 2017-12-25 | 1 | 2 |
| 2 | 2017-11-20 | 1 | 3 |
| 3 | 2017-11-20 | 1 | 3 |
| 5 | 2017-11-20 | 1 | 3 |
| 6 | 2017-11-20 | 1 | 3 |
| 7 | 2017-11-20 | 1 | 3 |
+----+------------+------+-----+
我希望在同一个查询中按月和按年SUM()
{strong}投票 WHERE id = 1
;和COUNT(DISTINCT(())
投票( num ),按月和按年分列。
这个想法是每个月都有一个人( id )投票的时间和投票数。如下例所示,如果我们选择 id = 2。
+----+-------+------+---------------+-------+
| id | month | year | participation | total |
+----+-------+------+---------------+-------+
| 2 | 1 | 2018 | 0 | 1 |
| 2 | 12 | 2017 | 0 | 1 |
| 2 | 11 | 2017 | 1 | 1 |
+----+-------+------+---------------+-------+
我尝试的所有查询都不好。
答案 0 :(得分:1)
select year(date) year, month(date) month, sum(vote) vote_sum, sum(distinct num) distinct_num_sum
from t as t1
where id = 1
group by year(date), month(date)
您可以在行动here中看到它。
答案 1 :(得分:1)
目前尚不清楚你要求的是什么。
请提供您当前的查询和预期的结果集。
到目前为止,这是我的方法:
http://sqlfiddle.com/#!9/29cc07/6
SELECT id,
YEAR(`date`) `year`,
MONTH(`date`) `month`,
SUM(vote),
SUM(num)
FROM votes
WHERE id = 1
GROUP BY id, `year`, `month`
ORDER BY `year`, `month`
更新 http://sqlfiddle.com/#!9/29cc07/21
SELECT id,
v_ym.year,
v_ym.month,
SUM(vote),
COUNT(DISTINCT(num))
FROM (
SELECT
YEAR(`date`) `year`,
MONTH(`date`) `month`
FROM votes
GROUP BY `year` ASC, `month` ASC
) v_ym
LEFT JOIN votes v
ON MONTH(v.`date`) = v_ym.month
AND YEAR(v.`date`) = v_ym.year
AND v.id = 2
GROUP BY id, v_ym.year, v_ym.month
ORDER BY `year` ASC, `month` ASC
答案 2 :(得分:-1)
我最近解决了这个问题,不幸的是,我的技能设置是tsql,而不是mysql。我可以从逻辑的角度解释如何解决这个问题,但是我无法用精确的代码示例解决它的问题。
您问题的最大部分是您希望数据不存在。在您的示例中,您期望记录计数(0),其中没有记录。你必须先创造一个记录。
如果您第一次拥有该记录,则可以将空记录更改为0。
这是具有一个月和一年的聚合的ID,更简单的方法是将日值保留为1,而不是将月份和年份分开。
您需要包含以下源数据:
+----+------------+------+-----+
| id | date | vote | num |
+----+------------+------+-----+
2 01-01-2018 null null
第一步是创建日期,在tsql中你可以这样做:
declare @date as table (
DateID int identity(1,1) not null primary key clustered
, StartDate date not null
, EndDate date not null
);
insert into @date (StartDate, EndDate)
select dateadd(day, 1, eomonth(sysdatetime(), -1)), eomonth(sysdatetime()) union all
select dateadd(day, 1, eomonth(sysdatetime(), -2)), eomonth(sysdatetime(), -1) union all
select dateadd(day, 1, eomonth(sysdatetime(), -3)), eomonth(sysdatetime(), -2) union all
select dateadd(day, 1, eomonth(sysdatetime(), -4)), eomonth(sysdatetime(), -3) union all
select dateadd(day, 1, eomonth(sysdatetime(), -5)), eomonth(sysdatetime(), -4) union all
select dateadd(day, 1, eomonth(sysdatetime(), -6)), eomonth(sysdatetime(), -5)
这会给你一个类似的结果集:
1 2018-01-01 2018-01-31
2 2017-12-01 2017-12-31
3 2017-11-01 2017-11-30
您可能已经注意到我在那里有两列,这是为了查找一个月的开始和结束日期,这允许您加入日期范围,抛弃使用月份和年份的整数的复杂性。
如果您的ID是任意的,您可以创建ID和日期,然后加入,但如果您的ID值更复杂,则需要使用交叉申请将日期应用于您的ID。
代码应该类似于:
;with cte as (
select *
from MyDataTable a
cross apply
(
select *
from @date b
) x
)
select ID
, RealDateDate
, FirstOfMonthDate
, EndOfMonthDate
from cte a
left join MyDataTable b
on a.ID = a.ID
and b.date between a.FirstOfMonthDate and a.EndOfMonthDate;
然后,您应该能够在该结果集上运行聚合以获得您正在查找的结果。
您应该能够根据您的选择查询获得结果集,如下所示:
+----+------------+------+-----+
| id | date | vote | num |
+----+------------+------+-----+
| 1 | 2018-01-01 | 1 | 1 |
| 3 | 2018-01-01 | 1 | 1 |
| 4 | 2018-01-01 | 1 | 1 |
| 5 | 2018-01-01 | 1 | 1 |
| 1 | 2018-01-01 | 1 | 1 |
| 3 | 2018-01-01 | 1 | 1 |
| 4 | 2018-01-01 | 1 | 1 |
| 2 | 2018-01-01 | null| null|
然后你使用诸如isnull(vote, 0)
之类的函数......这就是你的空值变为0的地方。