0

Is there a way to show only one of two rows that have the same date and id, by using another column that is a nvarchar.

IF I HAD:

groupID     Date         Task
1           1-01-1111    First Task
2           1-02-1122    First Task
2           1-02-1122    Second Task
3           1-03-1133    Second Task
3           1-03-1133    Third Task

I Would like to get:

groupID     Date         Task
1           1-01-1111    First Task
2           1-02-1122    First Task
3           1-03-1133    Second Task
3           1-03-1133    Third Task

If rows have the same groupID and Date AND if one of the Task in the rows are "First Task" only show the row with the Task of "First Task".

If rows have the same groupID and Date, but no row has a Task of "First Task", show all rows.

Demetrick Norris
  • 41
  • 1
  • 2
  • 9

3 Answers3

1

You can use row_number function to set task position per group and then just keep record with position set to 1. So in the following query, a task named "First task" will have the first position. If there is no such task, then you could let the SQL engine choose which one will be first, but this is a bad practice. So for this sake, here I specified alphabetic order on Task.

So this mean, 'First task' is first, otherwise 'another task' is.

SELECT  groupID,
        [Date],
        Task
FROM    (SELECT groupID,
                [Date],
                Task,
                i = ROW_NUMBER() OVER(PARTITION BY groupID, [Date] ORDER BY CASE WHEN UPPER(Task) = 'FIRST TASK' THEN 0 ELSE 1 END, Task)
        FROM @YourTableName) AS t
WHERE i = 1 --Only show the first row for a group with same groupID and Date

N.B : UPPER is used to handle possible data irregularity, like 'First Task', 'first task'.

Community
  • 1
  • 1
AXMIM
  • 2,424
  • 1
  • 20
  • 38
1

You can use a column Row_number with Partition where this column is 1.

select * from (
    Select groupID, Date, Task
    , row_number () over (Partition by goupId, Date, order by groupId, Date, Task) as line
) as t1
where
     t1.line = 1
Thiago
  • 56
  • 4
1

Given only your sample data, and stated requirement, I would do it like this:

WITH cte AS (
  SELECT *,
    ROW_NUMBER() OVER (Partition By GroupId, [Date] ORDER BY CASE
      WHEN Task = 'First Task' THEN 0
      ELSE 1
    END ASC)
  FROM MyTable
)
SELECT GroupId, [Date], Task FROM cte

If a given GroupId and Date has multiple rows, and none of them have "First Task" for the task, then one will be selected randomly.

Tab Alleman
  • 31,483
  • 7
  • 36
  • 52
  • Everyone one was on the right track, but the use of CASE in the ORDER BY part of the Partition is what I really needed to order the task in the desired way to get the results needed. I ended up taking the select and putting it in a LEFT JOIN. – Demetrick Norris Feb 04 '16 at 14:06