SQL查询 - 复杂,不太确定从哪里开始

时间:2016-02-16 17:51:20

标签: sql

我对这个糟糕的标题表示道歉,但我完全迷失了从这个开始的地方

我有两个表第一个表只有客户ID第二个表有一个我们与每个客户的交互列表这包括与约会有关的交互以及一堆交互类型,其中大多数我们没有致电

对于每个客户,我们希望日期和时间描述他们最后一次约会相关的互动(是否被取消,安排或有)以及最后一次处方补充的日期(如果存在)

TABLE_1

User_ID    
-------
  001 
  002 
  003

TABLE_2

User_ID    Date         Interaction
------------------------------------------------------
  001       1/21/2015   Canceled Appointment
  001      12/09/2014   Scheduled Appointment
  001      12/01/2014   Called to Refill Prescription
  002       2/1/2015    Had Appointment
  002      12/2/2014    Called About Symptoms
  002      11/18/2014   Scheduled Appointment
  003       2/1/2015    Called to Refill Prescription
  003      11/28/2014   Had Appointment

所需的输出

User_ID   Date         Appointment_Details      Prescription Refill Date
------------------------------------------------------------------------
 001       1/21/2015   Canceled Appointment     12/01/2014
 002       2/1/2015    Had Appointment          n/a
 003      11/28/2014   Had Appointment          2/1/2015

4 个答案:

答案 0 :(得分:2)

最好通过三个步骤解决这个问题:

对于每个User_ID,选择交互在列表“已取消约会”,“预约约会”或“已预约”中的最后一条记录。为此,我们可以使用相关子查询来查找交互在该列表中的每个user_id的最大值(日期)。

SELECT 
    user_id,
    DATE,
    interaction
FROM table_2 t2
WHERE DATE IN (
        SELECT max(DATE)
        FROM table_2
        WHERE t2.user_id = user_id
            AND Interaction IN (
                'Cancelled Appointment',
                'Scheduled Appointment',
                'Had Appointment'
                )
        )

对于每个User_ID,选择交互“被调用以重新填写处方”的记录。这个有点简单,因为只需要过滤“叫来补充处方”。

SELECT user_id, date FROM table_2 WHERE Interaction = 'Called To Refill Prescription'

现在我们只使用LEFT OUTER JOIN将它们连接在一起,因此我们从第一个记录集中获取所有记录,并且只从第二个记录集中获取匹配的记录

SELECT
    t1.user_id,
    t1.date
    t1.Interaction as Appointment_Details
    t2.date as Prescription_Refill_Date
FROM
    (
        SELECT 
            user_id,
            DATE,
            interaction
        FROM table_2 t2
        WHERE DATE IN (
                SELECT max(DATE)
                FROM table_2
                WHERE t2.user_id = user_id
                    AND Interaction IN (
                        'Cancelled Appointment',
                        'Scheduled Appointment',
                        'Had Appointment'
                        )
                )   
    ) t1
    LEFT OUTER JOIN (SELECT user_id, date FROM table_2 WHERE Interaction = 'Called To Refill Prescription') t3
        ON t1.user_id = t3.user_id

这里的一个重要警告是,只有当user_id出现在全套(一系列预定/取消/已预约和一个“被叫重新填写处方”)时,他才真正有效。如果需要通过多次访问和多次处方补充来显示user_id,事情会变得有点麻烦。此外,如果安排和取消或安排并在同一天约会,您将得到重复。这是因为没有任何逻辑说明最后发生了什么。无论哪种方式,这应该让你进入球场。

答案 1 :(得分:1)

如果你使用sql server,这应该这样做:

创建样本数据:

CREATE TABLE #Temp1 ([User_ID] VARCHAR(5) )
INSERT INTO #Temp1
VALUES('001'),('002'),('003')

CREATE TABLE #Temp2 ([User_ID] VARCHAR(5),[Date] DATE, Interaction VARCHAR(50))
INSERT INTO #Temp2
VALUES('001','1/21/2015','Canceled Appointment'),

('001','12/09/2014','Scheduled Appointment'),

('001','12/01/2014','Called to Refill Prescription'),

('002','2/1/2015','Had Appointment'),

('002','12/2/2014','Called About Symptoms'),

('002','11/18/2014','Scheduled Appointment'),

('003','2/1/2015','Called to Refill Prescription'),

('003','11/28/2014','Had Appointment')

使用PIVOT查询:

    SELECT  [User_ID],
       COALESCE([Had Appointment], [Canceled Appointment]) AS [Date],
       CASE  WHEN [Had Appointment] IS NULL AND [Canceled Appointment] IS NOT NULL THEN 'Canceled Appointment' 
             WHEN [Had Appointment] IS NOT NULL AND [Canceled Appointment] IS NULL THEN 'Had Appointment ' 
       END AS [Appointment_Details], 
       [Called to Refill Prescription]
FROM 
(   SELECT *
    FROM #Temp2 AS B ) p
PIVOT
(   MIN([Date] )
    FOR [Interaction] IN    (   [Had Appointment],[Canceled Appointment],
       [Scheduled Appointment],
       [Called to Refill Prescription]  )
) AS pvt

结果:

enter image description here

如果您希望日期格式显示为美国格式dd / MM / yy,则可以将它们转换为varchar CONVERT(VARCHAR(10),<your column name>,1)

SELECT  [User_ID],
       CONVERT(VARCHAR(10),COALESCE([Had Appointment], [Canceled Appointment]),1) AS [Date],
       CASE  WHEN [Had Appointment] IS NULL AND [Canceled Appointment] IS NOT NULL THEN 'Canceled Appointment' 
             WHEN [Had Appointment] IS NOT NULL AND [Canceled Appointment] IS NULL THEN 'Had Appointment ' 
       END AS [Appointment_Details], 
       CONVERT(VARCHAR(10),[Called to Refill Prescription],1) AS [Called to Refill Prescription]
FROM 
(   SELECT *
    FROM #Temp2 AS B ) p
PIVOT
(   MIN([Date] )
    FOR [Interaction] IN    (   [Had Appointment],[Canceled Appointment],
       [Scheduled Appointment],
       [Called to Refill Prescription]  )
) AS pvt

结果:

enter image description here

答案 2 :(得分:0)

SELECT
    t1.user_id,
    t1.date
    t1.Interaction as Appointment_Details
    t2.date as Prescription_Refill_Date
FROM
    (
        SELECT 
            user_id,
            DATE,
            interaction
        FROM table_2 t2
        WHERE DATE IN (
                SELECT max(DATE)
                FROM table_2
                WHERE t2.user_id = user_id
                    AND Interaction IN (
                        'Cancelled Appointment',
                        'Scheduled Appointment',
                        'Had Appointment'
                        )
                )
            AND Interaction IN (
                SELECT max(Interaction)
                FROM table_2
                WHERE t2.user_id = user_id
                    AND Interaction IN (
                        'Cancelled Appointment',
                        'Scheduled Appointment',
                        'Had Appointment'
                        )
                    AND DATE = t2.date
                )      
    ) t1
    LEFT OUTER JOIN (SELECT max(date) FROM table_2 
                      WHERE Interaction = 'Called To Refill Prescription') t3
            ON t1.user_id = t3.user_id

这是Nevill的答案,包括避免重复。 您可以选择最大(交互)或最小(交互),因为您更喜欢“已取消”,“已暂停”或“已计划”约会显示的顺序。如果所有三个人都在同一个日期,那么唯一的就是你不能得到它。

当然可以使用CASE语句来完成,但这会使查询更加复杂。

答案 3 :(得分:0)

SELECT  t.[User_ID],
        t.[Date],
        t.[Interaction] [Appointment_Details],
        p.[Prescription Refill Date]
FROM    (SELECT Table_2.*,
                ROW_NUMBER() OVER (PARTITION BY Table_1.[User_ID] ORDER BY Table_2.[Date] DESC) Rn
         FROM   Table_1
                JOIN Table_2 ON Table_1.[User_ID] = Table_2.[User_ID]
         WHERE  [Interaction] IN ('Canceled Appointment', 'Scheduled Appointment', 'Had Appointment')
        ) t
        OUTER APPLY (SELECT MAX([Date]) [Prescription Refill Date]
                     FROM   Table_2
                     WHERE  t.[User_ID] = Table_2.[User_ID]
                            AND [Interaction] = 'Called to Refill Prescription'
                    ) p
WHERE   t.Rn = 1