按日期分组记录

时间:2014-01-13 07:40:21

标签: sql sql-server date select group-by

我正在使用SQL Server 2008 R2。我有一个如下所示的数据库表:

+--+-----+---+---------+--------+----------+-----------------------+
|Id|Total|New|Completed|Assigned|Unassigned|CreatedDtUTC           |
+--+-----+---+---------+--------+----------+-----------------------+
|1 |29   |1  |5        |6       |5         |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|2 |29   |1  |5        |6       |5         |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|3 |29   |1  |5        |6       |5         |2014-01-07 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|4 |30   |1  |3        |2       |3         |2014-01-08 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|5 |30   |0  |3        |4       |3         |2014-01-09 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|6 |30   |0  |0        |0       |0         |2014-01-10 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+
|7 |30   |0  |0        |0       |0         |2014-01-11 06:00:00.000|
+--+-----+---+---------+--------+----------+-----------------------+

现在,我在groupingCreatedDtUTC记录时遇到了一个奇怪的问题。

我想要此表中的distinct records。在这里,您可以观察到前三个记录是在同一日期时创建的重复。我想要不同的记录,所以我运行了下面给出的查询:

SELECT  Id, Total, New, Completed, Assigned, Unassigned, MAX(CreatedDtUTC) 
FROM TblUsage 
GROUP BY CreatedDtUTC

但它给了我错误:

列'TblUsage.Id'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

我也尝试过针对CreatedDtUTC列的DISTINCT,但是给出了同样的错误。任何人都可以让我知道如何摆脱这个?

P.S。我想要CreatedDtUTC格式CONVERT(VARCHAR(10), CreatedDtUTC,101)格式。

3 个答案:

答案 0 :(得分:2)

试试这个............

SELECT  min(Id) Id, Total, New, Completed, Assigned, Unassigned, CreatedDtUTC
FROM TblUsage 
GROUP BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC

答案 1 :(得分:1)

错误消息本身非常明确。如果列不是SELECT子句中的聚合函数,则不能将其放入GROUP BY子句中,如果它不是Id的一部分。其背后的原因非常简单,SQL Server不知道您要选择的组中该列的值。这不是确定性的,因此被禁止。

您可以将GROUP BY以外的所有列放在MIN()中,并在MAX()上使用IdROW_NUMBER(),也可以利用窗口函数{{1以下列方式

SELECT Id, Total, New, Completed, Assigned, Unassigned, CONVERT(VARCHAR(10), CreatedDtUTC,101) CreatedDtUTC
  FROM
(
  SELECT t.*, ROW_NUMBER() OVER (PARTITION BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC 
                                 ORDER BY id DESC) rnum
    FROM TblUsage t
) q
 WHERE rnum = 1

输出:

| ID | TOTAL | NEW | COMPLETED | ASSIGNED | UNASSIGNED | CREATEDDTUTC |
|----|-------|-----|-----------|----------|------------|--------------|
|  3 |    29 |   1 |         5 |        6 |          5 |   01/07/2014 |
|  6 |    30 |   0 |         0 |        0 |          0 |   01/10/2014 |
|  7 |    30 |   0 |         0 |        0 |          0 |   01/11/2014 |
|  5 |    30 |   0 |         3 |        4 |          3 |   01/09/2014 |
|  4 |    30 |   1 |         3 |        2 |          3 |   01/08/2014 |

这是 SQLFiddle 演示

答案 2 :(得分:0)

试试这个:

SELECT MIN(Id) AS Id, Total, New, Completed, Assigned, Unassigned, 
       CONVERT(VARCHAR(10), CreatedDtUTC, 101) AS CreatedDtUTC
FROM TblUsage 
GROUP BY Total, New, Completed, Assigned, Unassigned, CreatedDtUTC

检查SQL FIDDLE DEMO

<强>输出

| ID | TOTAL | NEW | COMPLETED | ASSIGNED | UNASSIGNED | CREATEDDTUTC |
|----|-------|-----|-----------|----------|------------|--------------|
|  1 |    29 |   1 |         5 |        6 |          5 |   01/07/2014 |
|  4 |    30 |   1 |         3 |        2 |          3 |   01/08/2014 |
|  5 |    30 |   0 |         3 |        4 |          3 |   01/09/2014 |
|  6 |    30 |   0 |         0 |        0 |          0 |   01/10/2014 |
|  7 |    30 |   0 |         0 |        0 |          0 |   01/11/2014 |