oracle查询计算多列中的出现次数

时间:2018-03-17 12:58:23

标签: oracle group-by count

我想检索基于三列共计至少2笔交易的客户。是 - 成功交易

EX:

Customer_Name  Col1    Col2    Col3
Customer1        Y       Y      N
Customer2        N       N      Y
Customer3        Y       Y      N

对于上表,我想显示如下输出(想要排除只进行一次交易的客户)

Customer1 - 2
Customer3 - 2

4 个答案:

答案 0 :(得分:1)

我看到有两个人使用汇总示例回答了您的问题。因为他们都使用GROUP BY和HAVING子句。您不一定需要使用任何类型的分组来获得所需的输出。请参阅下面的替代解决方案这可能只是一个意见,但我更喜欢这个解决方案:

WITH demo_data (cname, col1, col2, col3) AS
( /* Using CTE to produce fake table with data */
  SELECT 'cust1', 'Y', 'Y', 'N' FROM dual UNION ALL
  SELECT 'cust2', 'N', 'N', 'Y' FROM dual UNION ALL
  SELECT 'cust3', 'Y', 'N', 'Y' FROM dual UNION ALL
  SELECT 'cust4', 'Y', 'Y', 'Y' FROM dual UNION ALL
  SELECT 'cust5', 'Y', 'Y', 'N' FROM dual UNION ALL
  SELECT 'cust6', 'Y', 'N', 'N' FROM dual
)
, transform_data AS
( /* Using decode to convert all 'Y' and 'N' to numbers */
  SELECT cname
       , decode(col1, 'Y', 1, 0) AS col1
       , decode(col2, 'Y', 1, 0) AS col2
       , decode(col3, 'Y', 1, 0) AS col3
  FROM demo_data
)
/* Now we created our SUM column using the columns 1 thru 3 */
SELECT cname, col1, col2, col3
  /* I didn't need to create the sum_col however I added it for visual purposes */
  , col1 + col2 + col3 AS sum_col
FROM transform_data
WHERE col1 + col2 + col3 > 1
;

WITH子句生成的每个表的输出屏幕截图和实际所需的输出。

enter image description here

答案 1 :(得分:0)

您可以结合使用SUM()和HAVING()子句。

D:\Anaconda3\Scripts\spyder.exe

答案 2 :(得分:0)

有点类似于@anonyXmous'代码,但使用DECODE而不是那么多(不必要的?)SUMs:

SQL> with test (cname, col1, col2, col3) as
  2    (select 'cust1', 'y', 'y', 'n' from dual union
  3     select 'cust2', 'n', 'n', 'y' from dual union
  4     select 'cust3', 'y', 'n', 'y' from dual
  5    )
  6  select cname,
  7    sum(decode(col1, 'y', 1, 0) +
  8        decode(col2, 'y', 1, 0) +
  9        decode(col3, 'y', 1, 0)) sumc
 10  from test
 11  group by cname
 12  having sum(decode(col1, 'y', 1, 0) +
 13             decode(col2, 'y', 1, 0) +
 14             decode(col3, 'y', 1, 0)) >= 2
 15  order by cname;

CNAME       SUMC
----- ----------
cust1          2
cust3          2

SQL>

答案 3 :(得分:0)

从您所展示的内容看来:

  • 你有一个包含三个布尔列的表。由于Oracle DBMS仍然没有使用布尔数据类型,因此您使用了col1 CHAR(1) NOT NULL, CONSTRAINT chk_customers_bool_col1 CHECK (col1 in ('Y','N'))等。 (遗憾的是Oracle强迫我们应用这些解决方法。)
  • 您正在显示一个客户表,其中每个客户有一条记录和三个属性,您在示例中调用了col1col2col3,但它们是现实生活中的真正属性,例如quickfriendlyrich,并且您希望选择至少有两个属性为真的客户。

这样做的一个简单方法是连接三个字母,删除Ns并计算剩余的Y.

select
  Customer_Name, 
  length(replace(col1 || col2 ||| col3 ,'N',''))
from customers
where length(replace(col1 || col2 ||| col3 ,'N','')) >= 2;

此查询仍然适用于三态布尔值(即允许空值),但如果列可以包含其他字符(例如' M'用于"可能"或&# 39; S' for"有时")。在这种情况下,您必须使用CASE表达式或Oracle DECODE来检查Y.

许多人更喜欢数字0和1在Oracle中模拟布尔值false和true。与N'相比的一个优点是和' Y'是你可以快速添加它们来计算有多少是真的,这正是你的情况。 (在存在布尔数据类型的MySQL中,它们甚至允许用数学代替false,用0代替false,用1代替true,所以true + false + true = 2.)