【问题标题】:How to Count Distinct on Case When?如何区分大小写?
【发布时间】:2019-03-08 15:00:06
【问题描述】:

我今天一直在建立一个查询,但我卡住了。我有两个唯一的 ID,用于标识订单是内部还是 Web。我已经能够将其拆分出来,因此它可以计算它们出现的次数,但不幸的是它没有为我提供预期的结果。根据研究,我尝试创建一个 Count Distinct Case When 语句来为我提供结果。

请看下面我在哪里分解了它正在做什么以及我期望它如何。

原始数据如下:

Company Name       Order Date       Order Items      Orders     Value      REF
-------------------------------------------------------------------------------
CompanyA           03/01/2019        Item1           Order1      170       INT1
CompanyA           03/01/2019        Item2           Order1      0         INT1
CompanyA           03/01/2019        Item3           Order2      160       WEB2
CompanyA           03/01/2019        Item4           Order2      0         WEB2

我希望它是怎样的:

Company Name       Order Date       Order Items      Orders     Value      WEB       INT
-----------------------------------------------------------------------------------------
CompanyA           03/01/2019            4             2         330        1         1

目前的结果

Company Name       Order Date       Order Items      Orders     Value      WEB       INT
 -----------------------------------------------------------------------------------------
 CompanyA           03/01/2019            4             2         330        2         2

从我当前的结果中可以看出,它正在计算每一行,即使它是相同的引用。现在,它总是加倍并不是一个硬性规定。这就是为什么我认为我需要一个 Count Distinct Case When。以下是我目前正在使用的查询。这来自我通过 Excel 连接的 Progress V10 ODBC。不幸的是,我没有 SSMS,Microsoft Query 也没用。

我当前的 SQL:

SELECT 

Company_0.CoaCompanyName
, SopOrder_0.SooOrderDate
, Count(DISTINCT SopOrder_0.SooOrderNumber) AS 'Orders'
, SUM(CASE WHEN SopOrder_0.SooOrderNumber IS NOT NULL THEN 1 ELSE 0 END) AS 'Order Items'
, SUM(SopOrderItem_0.SoiValue) AS 'Order Value'
, SUM(CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'INT%' THEN 1 ELSE 0 END) AS 'INT'
, SUM(CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'WEB%' THEN 1 ELSE 0 END) AS 'WEB'

FROM 

SBS.PUB.Company Company_0
, SBS.PUB.SopOrder SopOrder_0
, SBS.PUB.SopOrderItem SopOrderItem_0

WHERE 

SopOrder_0.SopOrderID = SopOrderItem_0.SopOrderID 
AND Company_0.CompanyID = SopOrder_0.CompanyID
AND SopOrder_0.SooOrderDate > '2019-01-01'

GROUP BY 

Company_0.CoaCompanyName
, SopOrder_0.SooOrderDate

我尝试使用以下行,但在导入时出现错误:

, Count(DISTINCT CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'INT%' THEN  SopOrder_0.SooParentOrderReference ELSE 0 END) AS 'INT'

知道我在导入时遇到的错误是“CASE WHEN sopOrder_0.SooParentOrderRefer”(10713) 处或附近的语法错误

【问题讨论】:

  • Count(0) 仍将返回 1。您可以尝试按照 @GordonLinoff 答案中的建议完全删除 else,或使用 ELSE null

标签: sql distinct openedge case-when progress-db


【解决方案1】:

尝试删除ELSE

COUNT(DISTINCT CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'INT%' THEN  SopOrder_0.SooParentOrderReference END) AS num_int

您没有指定错误,但问题可能是 THEN 返回一个字符串,而 ELSE 返回一个数字 - 因此尝试将字符串值转换为数字。

另外,学习使用正确、明确、标准 JOIN 语法。简单规则:永远不要FROM 子句中使用逗号。

【讨论】:

  • Hello Gordon 很抱歉,当我删除 ELSE 时,它仍然返回错误:在“CASE WHEN sopOrder_0.SooParentOrderRefer”(10713) 处或附近出现语法错误
【解决方案2】:

在 SooOrderNumber 或 SooParentOrderReference 上计数不同,以对您更有意义的为准。

如果您是COUNTing,则需要将NULL 设为您未计算在内的东西。我更喜欢在案例中包含 else ,因为它更加一致和完整。

, Count(DISTINCT CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'INT%' THEN  SopOrder_0.SooParentOrderReference ELSE null END) AS 'INT'

Gordon Linoff 关于您的错误来源是正确的,即 case 之间的数据类型不匹配,然后 value else value end。 null 消除(应该消除)这种歧义 - 我需要仔细检查。

正在编辑我之前的答案...

尽管它看起来像你所说的,在 Pervasive PSQL 中不支持 count distinct,但支持 CTE。所以你可以做类似...

这是您正在尝试执行的操作,但不受支持... 和 重复作为 ( 选择 1 作为 id,'A' 作为 col1 union all 选择 1,'A' union all select 1,'B' union all select 2,'B' ) 选择编号 ,count(distinct col1) as col_count 来自重复 按 id 分组;

在查询中粘贴另一个 CTE 以首先对数据进行重复数据删除。然后算正常。那应该可以...

with
dups as
(
select 1 as id, 'A' as col1 union all select 1, 'A' union all select 1, 'B' union all select 2, 'B'
)
,de_dup as
(
select id
      ,col1
  from dups
group by id
        ,col1
)
select id
      ,count(col1) as col_count
  from de_dup
group by id;

这两个版本应该给出相同的结果集。

总会有办法的!!

【讨论】:

  • 你好 Liam 我已经包含了你上面建议的内容,当我试图将它返回到 excel 时,错误仍然出现:在“CASE WHEN sopOrder_0.SooParentOrderRefer”处或附近出现语法错误(10713) 我在 select 语句中的代码现在是:, Count(DISTINCT CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'INT%' THEN SopOrder_0.SooParentOrderReference ELSE null END) AS 'INT' , Count(DISTINCT CASE WHEN SopOrder_0.SooParentOrderReference LIKE 'WEB%' THEN SopOrder_0.SooParentOrderReference ELSE null END) AS 'WEB'
  • 我不熟悉 Progress,我会尝试使用 DBeaver 之类的工具连接到您的数据库。在 Excel 中尝试每一个 select count(distinct case when 1 = 1 then 1 else null end); -- should return 1 select count(distinct case when 1 = 0 then 1 else null end); -- should return 0 如果这不起作用,那么 Progress 驱动程序不起作用。
  • 然后尝试... select count(case when 1 = 1 then 1 else null end); select count(case when 1 = 0 then 1 else null end); 如果这些确实有效并且不同的计数不起作用,那么在进行中不会实现计数/不同。
  • 你好 Liam 选择计数(情况下工作正常,因为我让它进一步工作。我想我会坚持这样一个事实,即 Progress 不支持计数(不同情况下
【解决方案3】:

我无法解释您遇到的错误。您错误地使用单引号作为别名,但我实际上并不认为这是导致错误的原因。

无论如何,我建议您先汇总每个订单的订单商品,然后再加入:

SELECT
  c.coacompanyname
, so.sooorderdate
, COUNT(*) AS orders
, SUM(soi.itemcount) AS order_items
, SUM(soi.ordervalue) AS order_value
, COUNT(CASE WHEN so.sooparentorderreference LIKE 'INT%' THEN 1 END) AS int
, COUNT(CASE WHEN so.sooparentorderreference LIKE 'WEB%' THEN 1 END) AS web
FROM sbs.pub.company c
JOIN sbs.pub.soporder so ON so.companyid = c.companyid
JOIN 
(
  SELECT soporderid, COUNT(*) AS itemcount, SUM(soivalue) AS ordervalue
  FROM sbs.pub.soporderitem
  GROUP BY soporderid
) soi ON soi.soporderid = so.soporderid
GROUP BY c.coacompanyname, so.sooorderdate
ORDER BY c.coacompanyname, so.sooorderdate;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-06
    • 2011-10-14
    • 1970-01-01
    • 2014-07-19
    • 2012-12-01
    • 2020-02-18
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多