sql case语句IN with group by

时间:2017-06-04 15:06:50

标签: sql case

我有一个包含列的2列表:“user_name”和“characteristic”。每个user_name可能会出现多次,具有不同的特征。

特征中的值是:

  • 在线
  • 店内
  • 帐户
  • 电子邮件

我想写一个像这样的sql语句 - 但显然这不起作用:

connection

基本上第一个是一个标志,我检查该user_name是否存在任何值。 第二个字段是他们符合此标准并且符合“电子邮件”或“帐户”的标准

4 个答案:

答案 0 :(得分:1)

数据结构的一个示例有助于更好地了解您要完成的任务。但我想我得到了你想做的事。

您必须使用聚合函数才能使用group by。 像SUM或AVG这样的东西。

但是您首先需要构建数据的轴,然后您可以使用该轴来检查您的标准:

这将创建一个表轴,为每条记录显示符合标准的内容:

SELECT 
   user_name, 
   case when characteristic = "online"  then 1 else 0 end as online_yn,
   case when characteristic = "instore" then 1 else 0 end as instore_yn,
   case when characteristic = "account" then 1 else 0 end as account_yn,
   case when characteristic = "email"   then 1 else 0 end as email_yn,
FROM my_table

现在您可能要做的是创建按user_name分组的这些条目的平均版本,并使用这些平均值来创建您想要的字段。为此,您需要使用先前创建的同一语句作为内联表:

Select
   user_name,
   case when avg(online_yn + instore_yn) >= 1 then 1 else 0 end as purchase_yn,
   case when avg(online_yn + instore_yn) >= 1 and avg(email_yn + account_yn) >= 1 then 1 else 0 end as purchaser_with_account
From
    (SELECT 
       user_name, 
       case when characteristic = "online"  then 1 else 0 end as online_yn,
       case when characteristic = "instore" then 1 else 0 end as instore_yn,
       case when characteristic = "account" then 1 else 0 end as account_yn,
       case when characteristic = "email"   then 1 else 0 end as email_yn,
     FROM my_table) avg_table

group by
   user_name;

这应该有所帮助。

在性能方面可能效率不高,但你会得到你想要的东西。

答案 1 :(得分:0)

您只需将allpages表达式括在CASE聚合:

COUNT

如果SELECT user_name, COUNT(case when characteristic in ("online","instore") then 1 END) as purchase_yn, COUNT(case when characteristic in ("email",'account') then 1 END) as user_with_account FROM my_table GROUP BY user_name ,则设置第一个标志。如果purchase_yn > 0 purchase_yn > 0,那么您也会设置第二个标记。

注意:您必须从user_with_account > 0表达式中删除ELSE 0,因为CASE会考虑所有非空值。

答案 2 :(得分:0)

您还没有提到具体的RDBMS,但如果SUM(DISTINCT ...)可用,则以下内容非常好:

SELECT
    username,
    SUM(DISTINCT
        CASE
            WHEN characteristic in ('online','instore') THEN 1
            ELSE 0
        END) AS purchase_yn,
    CASE WHEN (
        SUM(DISTINCT
            CASE
                WHEN characteristic in ('online','instore') THEN 1
                WHEN characteristic in ('email','account') THEN 2
            ELSE 0 END
       )
    ) = 3 THEN 1 ELSE 0 END as purchaser_with_account
FROM
    my_table
GROUP BY
    username

答案 3 :(得分:0)

如果我正确理解,如果用户有'在线'或'店主',那么对于此用户,您希望1为purchase_yn列,如果用户也有“电子邮件”或“帐户”,则为1 purchaser_with_account列。

如果这是正确的,那么一种方法是:

with your_table(user_name, characteristic) as(
    select 1, 'online' union all
    select 1, 'instore' union all
    select 1, 'account' union all
    select 1, 'email' union all
    select 2, 'account' union all
    select 2, 'email' union all
    select 3, 'online'  
)

-- below is actual query:

select your_table.user_name, coalesce(max(t1.purchase_yn), 0) as purchase_yn, coalesce(max(t2.purchaser_with_account), 0) as purchaser_with_account 
from your_table
left join (SELECT user_name, 1 as purchase_yn from your_table where characteristic in('online','instore') ) t1
on your_table.user_name = t1.user_name
left join (SELECT user_name, 1 as purchaser_with_account  from your_table where characteristic in('email', 'account') ) t2 
on t1.user_name = t2.user_name
group by your_table.user_name