SQL Server SQL Table- Combine Rows Based on Conditions [duplicate]

2guxujil  于 2023-10-15  发布在  其他
关注(0)|答案(3)|浏览(109)

This question already has answers here:

Comma separated results in SQL (5 answers)
Closed 2 days ago.

I have a table like

DateCol       TaskID     EventName
2017-09-25    10         A
2017-07-26    10         B
2017-07-27    10         A
2017-09-14    10         A
2017-07-25    10         B
2017-09-25    10         C
2017-09-28    11         A
2017-11-01    11         D
2017-11-01    11         C

.....many thousands of rows

What I'd like is an output that, for each TaskID, if events A and C (not any other combination) occurred on the same day (from DateCol), EventName column is "A+C". So in this case it would show

DateCol       TaskID     EventName
2017-09-25    10         A+C
2017-07-26    10         B
2017-07-27    10         A
2017-09-14    10         A
2017-07-25    10         B
2017-09-28    11         A
2017-11-01    11         D
2017-11-01    11         C

You can see that row

2017-09-25    10         A

and

2017-09-25    10         C

are now one row,

2017-09-25    10         A+C

but nothing else is changed.

What kind of SQL statement would I have to do to make such an adjustment?

93ze6v8z

93ze6v8z1#

assumption : only combine 2 different EventName into 1.

a bit crude, but it should work.

; with
cte as
(
    select  t.DateCol, t.TaskID, 
        t.EventName,
        new_EventName   = 
            case when   t.EventName in ('A')        
                 and    max(t.EventName) over (partition by t.DateCol, t.TaskID)    = 'C'
                 then   'A+C'
                 when   t.EventName in ('C')
                 and    min(t.EventName) over (partition by t.DateCol, t.TaskID)    = 'A'
                 then   'A+C'
                 else   NULL
                 end
    from    yourtable t
)
select  distinct DateCol, TaskID, EventName = coalesce(new_EventName, EventName)
from    cte

if there are other scenario that this does not work, please post the sample data with the expected result

9bfwbjaz

9bfwbjaz2#

I believe the most efficient way to do this would be a self- JOIN .

SELECT DISTINCT
    mt1.DateCol, 
    mt1.TaskId,
    (CASE 
        WHEN mt2.EventName IS NULL THEN mt1.EventName 
        ELSE 'A+C' 
    END) as EventName
FROM 
    MyTable mt1
LEFT JOIN MyTable mt2 ON 
    mt1.DateCol = mt2.DateCol 
    AND ((mt1.EventName = 'A' AND mt2.EventName = 'C') OR (mt1.EventName = 'C' AND mt2.EventName = 'A'))

SQL Fiddle

svujldwt

svujldwt3#

So first you need a primary key/ unique column for all row.Then we find all the row who have A and C on the same date. We can use selfjoin for this. Also I assume the TaskId between EventName A and C is always the same.

For example if the Table name is TableX and primary key column is PrimaryX

Select A.DateCol, A.TaskID, 'A+C' AS EventName FROM TableX A INNER JOIN TableX B 
ON A.DateCol = B.DateCol AND (EventName ='A' OR EventName ='C')

Then we union with the normal but the normal query do not take the same data from our previous query. For this we can use not in on column PrimaryX

Select DateCol, TaskID, 'A+C' AS EventName FROM TableX A WHERE PrimaryX not in 
(Select A.PrimaryX  AS EventName FROM TableX A INNER JOIN TableX B 
ON A.DateCol = B.DateCol AND (EventName ='A' OR EventName ='C')) AND PrimaryX not in 
(Select B.PrimaryX  AS EventName FROM TableX A INNER JOIN TableX B 
ON A.DateCol = B.DateCol AND (EventName ='A' OR EventName ='C'))
UNION
Select A.DateCol, A.TaskID, 'A+C' AS EventName FROM TableX A INNER JOIN TableX B 
ON A.DateCol = B.DateCol AND (EventName ='A' OR EventName ='C')

相关问题