基于列值使用GROUP BY时返回唯一行

时间:2016-06-14 12:32:54

标签: sql sql-server

好吧,我们可以说有3张桌子: 日历,用户和请求。

Calendar.ID,Users.ID和requests.ID都是唯一的。 (如果那很重要)

我正在尝试从dbo.Calendar和users.color以及requests.Status中提取所有内容

SELECT calendar.ID, calendar.date, calendar.type, calendar.userID, users.color, requests.status
FROM calendar LEFT OUTER JOIN
    requests ON calendar.ID = requests.calendarID LEFT OUTER JOIN
        users ON calendar.userID = users.userID
WHERE(calendar.date >= '2016-06-01') AND (calendar.date <= '2016-12-30')
group by calendar.id, calendar.date, calendar.type, calendar.userID, users.color, requests.status

我面临的问题是,如果有完成的请求,我会得到一个重复的行,但在这种情况下,它应该只显示“待定”。

ID  date        type    userID  color       status
4   2016-06-16  RE      A       #cc99ff     pending
5   2016-06-17  RE      A       #cc99ff     accepted
5   2016-06-17  RE      A       #cc99ff     pending
6   2016-06-13  LM      B       #ffff99     NULL
7   2016-06-13  LM      B       #ffff99     accepted

我正试图解决这个问题:

ID  date        type    userID  color       status
4   2016-06-16  RE      A       #cc99ff     pending
5   2016-06-17  RE      A       #cc99ff     pending
6   2016-06-13  LM      B       #ffff99     NULL
7   2016-06-13  LM      B       #ffff99     accepted

仅供参考我8年来没有触及SQL,这只是我正在进行的个人项目。

2 个答案:

答案 0 :(得分:1)

您似乎希望每个id和用户占一行,但优先级为:

SELECT *
FROM (SELECT c.ID, c.date, c.type, u.userID, u.color, r.status,
             ROW_NUMBER() OVER (PARTITION BY c.ID, u.userID
                                ORDER BY (CASE WHEN r.status = 'Accepted' then 1  
                                               ELSE 2
                                          END) desc
                               ) as seqnum
      FROM calendar c LEFT OUTER JOIN
           requests r
           ON c.ID = r.calendarID LEFT OUTER JOIN
           users u
           ON c.userID = u.userID
      WHERE (c.date >= '2016-06-01') AND (c.date <= '2016-12-30')
    ) rcu
WHERE seqnum = 1;

答案 1 :(得分:0)

你没有使用聚合函数,那么你不需要分组 如果你想要不同的行,最终在你的选择中使用disctinct 对于statu添加条件status != 'accepted'

    SELECT calendar.ID, calendar.date, calendar.type, calendar.userID, users.color, requests.status
    FROM calendar LEFT OUTER JOIN
        requests ON calendar.ID = requests.calendarID LEFT OUTER JOIN
            users ON calendar.userID = users.userID
    WHERE(calendar.date >= '2016-06-01') AND (calendar.date <= '2016-12-30')
    AND requests.status != 'accepted' ;