【问题标题】:Use Joined SQL query as filter for another SQL query使用 Joined SQL 查询作为另一个 SQL 查询的过滤器
【发布时间】:2018-12-11 08:40:51
【问题描述】:

目前我有一些数据存储在 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

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

因此,如果呼叫 1 通过 peg 1 2 3 4 5 而呼叫 2 通过 peg 2 3 4 5 而呼叫 3 通过 1 3 4 5 那么我将获得呼叫 1 和 3 的所有数据,但不是呼叫 2。

我不能只根据通过 peg 1 的任何通话记录进行过滤,因为我需要存储在附加列中的信息,用于呼叫通过的其他 peg。

这真的超出了我对 SQL 的舒适区,我无法找到解决方案。

【问题讨论】:

标签: sql sql-server tableau-api


【解决方案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
            )

【讨论】:

  • 我假设使用 PEG_LOG.PEG AS PEG,而不是 seq_nbr 将是相同的逻辑?稍后我会在这里测试一下,看看这是否能满足我的需求
  • 这工作谢谢!因为我正在使用 tableau 并且 tableau 用 sql 做了一些时髦的东西我不打算尝试你的其他响应(使用 with 语句很时髦)。
【解决方案2】:

这些是我将采取的步骤:

  • 做一个 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 语句,您可以根据需要更轻松地适应其他序列号。

【讨论】:

  • ....这是一种不寻常的查询方式。如果带有seq_nbr = 1 的行的百分比很小,则查询性能可能很差(索引不太可能有帮助)。
  • @Clockwork-Muse,你会提出一个存在逻辑吗?我开始这样做,但转向 CTE。
  • EXISTS 是这个查询更常用的形式,是的(CTE 无关,因为它也可以作为子查询完成)。尤其是因为它更符合所提问题的意图。
【解决方案3】:

这在 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

结果:(去掉 Distinct 得到其他列)

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

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 2010-11-13
    • 1970-01-01
    • 2012-03-20
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多