【问题标题】:SQL Case and Cast in Count functionSQL Case 和 Cast in Count 函数
【发布时间】:2016-06-17 15:48:51
【问题描述】:

我试图仅在两个字段满足特定条件时才计算它们的记录。
这个 [Is it possible to specify condition in Count()?] 帖子很有帮助,但它没有考虑将 varchar 转换为 int。
这是我的代码:

SELECT Mailing_Id ,Mailing_Nm,Subject_Line,Campaign_Nm,Start_Ts,End_Ts, Mailed_Cnt, Invalid_Cnt ,Actual_Sent_Cnt ,Bounce_Cnt ,Open_Cnt ,Click_Cnt
,count(case ag.logtype when '7' then 1 end) as Unsubs
,count(case ag.category when '1' then 1 end) as Block
,count(case ag.category when '2' then 1 end) as Hard
,count(case ag.category when '3' then 1 end) as Soft
,count(case ag.category when '4' then 1 end) as Tech
,count(case ag.category when '9' then 1 end) as Unknown
  FROM [StrongMailTracking].[dbo].[SM_MAILING_SUMMARY] ms left join sm_aggregate_log ag on ms.mailing_id = ag.mailingid
  WHERE datepart(year,start_ts) = 2015 and (mailing_nm not like '%delivery report%' and mailing_nm not like '%daily helpdesk%' and mailing_nm not like '%test%')
  GROUP BY Mailing_Id ,Mailing_Nm ,Subject_Line ,Campaign_Nm ,Start_Ts ,End_Ts ,Mailed_Cnt ,Invalid_Cnt ,Actual_Sent_Cnt ,Bounce_Cnt ,Open_Cnt ,Click_Cnt
ORDER BY mailing_id asc


请注意这 6 个案例陈述。日志类型是 int,类别是 varchar。
我试过了:

  • 删除单引号
  • 当 ...
  • 在投射时删除单引号
  • 先转换为数字然后再转换为整数
    但我不断收到此错误:“Msg 245, Level 16, State 1, Line 1 将 varchar 值 'dynamic-preview-7179' 转换为数据类型 int 时转换失败。”

    有人知道该怎么做吗?

【问题讨论】:

  • 我认为这没有问题。除非数据类型是 int,否则您将字符串与 int 进行比较
  • 问题是不能在SQL case 语句中使用两种数据类型。它只能返回一种数据类型,并且它的选择方式有一个偏好顺序。使用 Gordon Linoffs 的答案。 msdn.microsoft.com/en-us/library/ms181765.aspx如果您想了解更多信息,请在该帖子中搜索数据类型。
  • @Sam Gordon 的回答无效,请查看我的评论
  • 您是否必须删除所有计数语句才能使该查询正常工作,或者您是否尝试删除每个计数语句以查看导致问题的原因?
  • 还要检查 sm_aggregate_log 表中的字段 logtye 和 category 以查看其中包含 'dynamic-preview-7179'

标签: sql sql-server


【解决方案1】:

根据您对数据类型的描述,这应该可以:

count(case ag.logtype when 7 then 1 end) as Unsubs,
count(case ag.category when '1' then 1 end) as Block,
count(case ag.category when '2' then 1 end) as Hard,
count(case ag.category when '3' then 1 end) as Soft,
count(case ag.category when '4' then 1 end) as Tech,
count(case ag.category when '9' then 1 end) as Unknown

数字应该与数字常量进行比较;字符串到字符串常量。

虽然等价,但我会将逻辑写成:

sum(case when ag.logtype = 7 then 1 else 0 end) as Unsubs,

为什么?两个仅仅是偏好的原因:

  • 我更喜欢更通用的case语句,因为我发现在修改代码时,我经常需要添加新的条件。我更喜欢IN 而不是使用多个WHENs。
  • 比起count(),我更喜欢sum(),因为count(2) = count(1)

【讨论】:

  • 我确实尝试过,但是我只是复制并粘贴了您的代码以进行仔细检查。我仍然收到同样的错误:“将 varchar 值 'dynamic-preview-7179' 转换为数据类型 int 时,Msg 245, Level 16, State 1, Line 1 Conversion failed。”
  • @z0nia 。 . .在这种情况下,问题将不在于聚合。我认为明显的转换可能性是join 条件:` ms.mailing_id = ag.mailingid`。
  • 我应该补充一点,当我删除 6 个计数语句时,查询可以工作! (话虽如此,ms.mailing_id 是 int 而 ag.mailingid 是 varchar)
  • 还有其他建议吗?
  • @z0nia 。 . .什么都没有想到。如果这些类型如您所说,我看不出COUNT() 会如何产生错误。
【解决方案2】:

正如我之前评论的那样,ms.Mailing_Id 是一个 int,而 ag.mailingid 是一个 varchar。一位同事帮我解决了这个问题:

FROM [StrongMailTracking].[dbo].[SM_MAILING_SUMMARY] ms left join sm_aggregate_log ag on CAST(ms.mailing_id As varchar(255)) = ag.mailingid

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 2018-10-27
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 2015-09-05
    相关资源
    最近更新 更多