使用Joined SQL查询作为另一个SQL查询的过滤器

时间:2018-12-06 18:28:45

标签: sql sql-server tableau

目前,我有一些数据存储在2个表Call_log(供参考的“ A”)和PEG_LOG(供参考的B)中。在表A中,它存储有关进入我们系统的呼叫的信息,并为每个呼叫提供一个callID。在表B中,它获取呼叫ID,并为流程中的每个步骤添加一个新行。要获取所有可用数据,我必须对A和B进行左连接

Select 
  Call_Log.IVR_CALL_ID AS CallLogCallID,
  Call_Log.CALL_START_DTM AS CallStartTime,
  Call_Log.CALL_END_DTM AS CallEndTime,
  call_Log.XFER_GROUP AS TransferGroup,
  Call_Log.DNIS AS DNIS,
  Call_log.ANI AS ANI,
  Call_log.XFER_NBR AS TransferNumber,
  Call_Log.Caller_data_1 AS CallBackNumber,
  Call_Log.Caller_data_2 AS UserID,
  Call_Log.Caller_data_3 AS CallerData3,
  Call_Log.SERVER AS Server,
  Call_Log.PBX_ID AS PBXID,
  Call_Log.CTI_ID AS CTIID,
  Call_Log.APP AS APP,
  Call_Log.LANGUAGE AS LANGUAGE,
  Call_Log.XFER_APP AS TransferApp,
  Call_Log.XFER_PEG AS TransferPeg,
  Call_Log.XFER_STATUS AS TransferStatus,
  Call_Log.ON_DUTY_FLAG AS OnDutyFlag,
  Call_Log.CALL_HANDLED AS CallHandled,
  Call_Log.TRANSFERRED AS Transferred,
  PEG_LOG.IVR_CALL_ID AS PEGCallID,
  PEG_LOG.SEQ_NBR AS SequenceNumber,
  PEG_LOG.APP AS PEGApp,
  PEG_LOG.TRANSFERRED AS PEGTransferred,
  PEG_LOG.PEG AS PEG,
  PEG_LOG.PEG_START_DTM AS PEGStart,
  PEG_LOG.PEG_END_DTM AS PEGEnd,
  PEG_LOG.RESPONSE AS UserResponse,
  PEG_LOG.REQUEST AS Request,
  PEG_LOG.RESPONSE_STATUS AS RepsonseStatus
From Call_Log
Left join PEG_LOG ON Call_Log.IVR_CALL_ID = PEG_LOG.IVR_CALL_ID

我需要做的是获取穿过钉1的所有calllogcallID(peg_log.Peg称为peg),然后使用这些calllogid作为过滤器提取所有数据

因此,如果呼叫1通过钉1 2 3 4 5而呼叫2通过钉2 3 4 5和呼叫3经过1 3 4 5,那么我将获得呼叫1和3的所有数据,但不会得到打电话2。

我不能仅基于通过钉1的任何呼叫日志进行过滤,因为我需要存储在其他列中的信息以用于其他通过钉的呼叫。

这确实超出了我对SQL的理解范围,并且我无法找到解决方案。

3 个答案:

答案 0 :(得分:1)

根据对我的其他回答@ Clockwork-Muse的评论,我将介绍我的原始方法。

老实说,它似乎更好,所以我可以删除其他答案。尽管我很好奇,但是如果您想同时测试这两种方法,并让我们知道这种方法实际上是否更快?

select      CallLogCallID = cl.ivr_call_id,
            -- other call_log columns here

            SequenceNumber = pl.seq_nbr,
            -- other peg_log columns here

from        call_log cl
left join   peg_log pl on cl.ivr_call_id = pl.ivr_call_id
where       exists (
                select  0
                from    peg_log plSub
                where   cl.ivr_call_id = plSub.ivr_call_id
                and     plSub.seq_nbr = 1
            )

答案 1 :(得分:0)

这些是我要采取的步骤:

  • 通过case语句确定peg_log表中的seq_nbr是否为1。如果是,则输出1,否则,则输出0。
  • 将此case语句包装在一个“ max”窗口函数中,该函数由call_log(ivr_call_id?)上的主键进行分区,因此如果我们的任何case语句都被归类为call_log主键,则它将输出“ 1”。请注意,窗口函数不会折叠您的数据。因此,您仍然拥有以前拥有的所有个人记录。我称这个为“ hasPegSeq1”。
  • 将所有这些都包装在公用表表达式(CTE)中,或者根据需要包装在子查询中。
  • 调用CTE中的所有记录,这些记录指示peg_log中针对call_log的至少一行为1。

下面是一些表示刚才所说内容的代码:

    with

        callAndPegLogs as (

            select      CallLogCallID = cl.ivr_call_id,
                        -- other call_log columns here

                        SequenceNumber = pl.seq_nbr,
                        -- other peg_log columns here,

                        hasPegSeq1 = 
                            max(case when pl.seq_nbr = 1 then 1 else 0 end) 
                            over (partition by cl.ivr_call_id)

            from        call_log cl
            left join   peg_log pl on cl.ivr_call_id = pl.ivr_call_id

        )

        select      *
        from        callAndPegLogs cpl
        where       hasPegSeq1 = 1

请注意,您可以将窗口函数更改为'min(pl.seq_nbr)'并获得相同的结果,但是使用case语句,可以根据需要更轻松地适应其他序列号。

答案 2 :(得分:0)

这在联接中为peg = 1使用子查询。这是你要的吗?

Declare @Call_log Table
(
IVR_CALL_ID Int,
otherfield VarChar(50)
)
Insert Into @call_log Values
(1,'xxxxx'),
(2,'yyyy'),
(3,'zzzzz'),
(4,'22222'),
(5,'333333')

Declare @Peg_Log Table
(
Id Int,
IVR_CALL_ID Int,
peg Int
)
Insert Into @Peg_log Values
(1,1,1),
(2,2,1),
(3,1,2),
(4,3,3),
(5,5,1)


Select Distinct c.IVR_CALL_ID
From 
   @Call_Log c Left join 
   @PEG_LOG p ON c.IVR_CALL_ID = p.IVR_CALL_ID INNER Join
   (Select IVR_CALL_ID From @Peg_Log Where peg =1) x ON c.IVR_CALL_ID = x.IVR_CALL_ID

结果:(删除其他列以获得其他列)

IVR_CALL_ID
-----------
1
2
5