SQL-如何合并行

时间:2019-03-21 14:22:58

标签: sql-server sql-server-2012

我有一张下表,该表查看电话和出勤情况。我通过在“电话”和“出勤”表上使用全部工会,然后在ID上使用行号并按日期排序来实现此目的。

表1:

     Type    | ID | Call/AttendanceDate | RowNum 
 ------------|----|---------------------|-------- 
  Attendance | 12 | 2018-09-16 10:11:00 |     82 
  Call       | 12 | 2018-09-18 14:11:47 |     83 
  Call       | 12 | 2018-10-02 17:26:13 |     84 
  Call       | 12 | 2018-10-05 14:58:31 |     85 
  Attendance | 12 | 2018-10-13 01:41:00 |     86 
  Call       | 12 | 2018-10-13 02:39:12 |     87 
  Call       | 12 | 2018-10-13 04:31:22 |     88 
  Attendance | 12 | 2018-10-13 14:29:00 |     89 
  Call       | 12 | 2018-10-13 14:59:19 |     90 
  Attendance | 12 | 2018-10-15 15:50:00 |     91 

我用于此的代码是:

WITH CTE1 AS
(
SELECT 'Call' as [Type], ID, CallDate AS Date1 
FROM CallsTable     

UNION ALL

SELECT 'Attendance' as [Type], ID, AttendanceDate AS Date2
FROM AttendanceTable] 
)

,CTE2 AS
(
SELECT [Type], Date1, ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date1 ASC) AS RowNum
FROM CTE1
)

--------------------------------OUTPUT--------------------------------

SELECT a.[Type], a.ID, a.Date1, a.RowNum
FROM CTE2 a
JOIN CTE2 b
    ON a.ID= b.ID
    AND a.RowNum = b.RowNum + 1
WHERE a.ID = '12'
ORDER BY ID, RowNum

我想将其修改为下面的输出,以便每当出席者跟随呼叫时,它都应该在同一行中。

表2:

  Type | ID |     CallDate     | RowNum |    Type    |  AttendanceDate  | RowNum 
 ------|----|------------------|--------|------------|------------------|-------- 
  NULL | 12 | NULL             | NULL   | Attendance | 16/09/2018 10:11 | 82     
  Call | 12 | 18/09/2018 14:11 | 83     | NULL       | NULL             | NULL   
  Call | 12 | 02/10/2018 17:26 | 84     | NULL       | NULL             | NULL   
  Call | 12 | 05/10/2018 14:58 | 85     | Attendance | 13/10/2018 01:41 | 86     
  Call | 12 | 13/10/2018 02:39 | 87     | NULL       | NULL             | NULL   
  Call | 12 | 13/10/2018 04:31 | 88     | Attendance | 13/10/2018 14:29 | 89     
  Call | 12 | 13/10/2018 14:59 | 90     | Attendance | 15/10/2018 15:50 | 91  

这可能吗?我可以使用什么代码?

3 个答案:

答案 0 :(得分:3)

使用完全加入

x = np.array([df.dse])
a_masked = np.ma.masked_less_equal(x, 0.0002)

# plot the full line
plt.plot(x, 'k')

# plot only the large values
plt.plot(a_masked, 'r', linewidth=2)

# add the threshold value (optional)
plt.axhline(0.00002, color='k', linestyle='--')
plt.plot('dse',data = df)
plt.show()

答案 1 :(得分:0)

您可以使用APPLY

SELECT C.[Type], C.ID, C.CallDate, C.RowNum,
       (CASE WHEN C2.RowNum - C.RowNum = 1 THEN C2.[TYPE] end) [TYPE],
       (CASE WHEN C2.RowNum - C.RowNum = 1 THEN C2.CallDate end) AttendanceDate,    
       (CASE WHEN C2.RowNum - C.RowNum = 1 THEN C2.RowNum end) RowNum    
FROM CTE2 C OUTER APPLY
     (SELECT TOP (1) C2.*
      FROM CTE2 C2
      WHERE C2.ID = C.ID AND C2.[Type] = 'Attendance' AND C2.RowNum > C.RowNum
      ORDER BY C2.RowNum
     ) C2
WHERE C.ID = 12 AND C.[Type] = 'Call';

答案 2 :(得分:0)

不太优雅,但对我有用,是一个表值函数

alter FUNCTION GetCallActivity()
RETURNS @activityTable TABLE 
(
  call_type     varchar(16),
  call_id       int, 
  call_date     datetime, 
  call_rownum   int,
  atnd_type     varchar(16),
  atnd_id       int, 
  atnd_date     datetime, 
  atnd_rownum   int
)
AS
BEGIN
    -- initialize the return table
    insert into @activityTable
    (call_type, call_id, call_date, call_rownum )
    select a.type, a.id, a.activity_date, a.rownum
    from   stack_calls  a
    where  a.type = 'Call'
    order  by a.activity_date;

    -- match to the attendence recs to the call recs
    update @activityTable
    set    atnd_type     = b.type,
           atnd_id       = b.id,
           atnd_date     = b.activity_date,
           atnd_rownum   = b.rownum
    from   stack_calls     b
    join   @activityTable  a
      on   b.rownum = a.call_rownum + 1
    where  b.type = 'Attendance';      

    -- deal with the edge cases
    insert into @activityTable
    ( atnd_type, atnd_id, atnd_date, atnd_rownum )
    select x.type, 
           x.id, 
           x.activity_date,
           x.rownum
    from 
    (
        select a.type, 
               a.id, 
               a.activity_date,
               a.rownum,
               lag(a.type, 1) over (order by a.activity_date) as prev_type 
        from   stack_calls  a
        where  a.type = 'Attendance'
    ) x
    where x.prev_type is null

    RETURN 
END
GO