在SQL中选择两个变量,一个包含WHERE

时间:2018-01-29 19:09:13

标签: mysql sql database where

我有一张投票表: id 是投票的人,投票 = 1是他参与的事实, num 是投票数。

我想从同一个查询中选择两个变量,而一个WHERE条件只适用于一个变量。使用GROUP BYYEAR(),这两个变量应该是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 |
+----+-------+------+---------------+-------+

我尝试的所有查询都不好。

3 个答案:

答案 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的地方。