【问题标题】:Multiple rows for same user - but I do not need all of them同一用户的多行 - 但我不需要所有这些
【发布时间】:2017-11-06 14:05:05
【问题描述】:

我有一个如下所示的表格:

USER_ID START_DATE END_DATE     PRODUCT_ID
1       2015-07-20 2016-07-20   1
1       2003-10-25 2009-01-14   0
2       2007-10-04 2008-05-05   1

等等。

我想要创建的是这样的表:

USER_ID   PAYER   EXPAYER   BASIC
1         0       1         0
2         0       0         1

我确实需要这样,因为我想在之后加入它并按城市分组。 但是,我在每个 USER_D 的表中有多个条目(如上所示)。

我将付款人定义为具有条目 PRODUCT_ID=1 的人,因此今天的日期介于 START 和 END_DATE 之间。

前付款人是指至少有一个这样的条目并且不再有的人。

基本客户是其他任何人。

通过这样做:

CREATE OR REPLACE TABLE MEMBERSHIP AS
SELECT 
  USER_ID, 
  COUNT( CASE WHEN PRODUCT_ID=1 AND (CURRENT_DATE BETWEEN DG_START_DATE AND DG_END_DATE) THEN 1 END ) AS 'PAYER', 
  COUNT( CASE WHEN PRODUCT_ID=1 AND (CURRENT_DATE NOT BETWEEN DG_START_DATE AND DG_END_DATE) THEN 1 END ) AS 'EXPAYER', 
  COUNT( CASE WHEN NET_PRICE = 0  THEN 1 END ) AS 'BASIC' 
FROM CONTRACTS;

但是,我的结果有例如这样的条目,这是错误的:

USER_ID    PAYER     EXPAYER    BASIC
1          4         2          4

等等……

非常感谢!

【问题讨论】:

  • NET_PRICE 来自哪里?您的示例数据和所需的输出不匹配。 columnBASIC的逻辑是什么?
  • 顺便说一句:您确定要使用会话相关的CURRENT_DATE 而不是SYSDATE 吗?
  • 简单的复制粘贴错误。想让我的问题尽可能简单,NET_PRICE 在这里并不重要,但存在于实际表中。我不知道使用 CURRENT_DATE 的错误,谢谢。

标签: sql oracle rows


【解决方案1】:

您应该使用SUM 而不是COUNT

COUNT( CASE WHEN PRODUCT_ID=1 ... 

应该变成

SUM (CASE WHEN PRODUCT_ID=1 ... then 1 else 0 end)

【讨论】:

  • SUM 在 1 和 0 上只是在非空值上写 COUNT 的另一种方式。也许你的意思是MAX
  • 你是对的,计算非空值也是一样的。我更喜欢 Sum,因为它对我来说更清楚。 @ThorstenKettner
【解决方案2】:

您的插入语句应该会导致语法错误,因为它缺少GROUP BY user_id。此外,您在别名上使用单引号,这应该是双引号(尽管它们在这里完全是多余的)。

三种类型相互排斥;用户是要么付款人付款人基本。因此,为此使用一个 CASE 构造。您可以在第二步中创建这三个不同的列,但这没有多大意义,因为总是一列为 1,其他列为 0。更好的选择是类型的第二个表和类型的一列成员表。

create or replace table membership as 
select 
  user_id,
  case when type = 'payer' then 1 else 0 end as payer,
  case when type = 'expayer' then 1 else 0 end as expayer,
  case when type = 'basic' then 1 else 0 end as basic
from
(
  select 
    user_id, 
    case when count(case when product_id = 1 and current_date between dg_start_date and dg_end_date then 1 end) > 0 then 'payer'
         when count(case when product_id = 1 then 1 end) > 0 then 'expayer'
         else 'basic'
    end as type
  from contracts
  group by user_id
);

【讨论】:

  • 谢谢伙计,这句话最有效。但是,它不适用于内部选择中的第二个“when”语句。 [当计数(当 product_id = 1 时的情况)> 0 然后是'expayer']。它给了我一个语法错误,“意外的')',期待 OR_ 或 THEN_)
  • 哦,对不起。我现在才看到你的cmets。我已经更正了我的答案中有缺陷的大小写表达。
猜你喜欢
  • 2020-10-29
  • 2010-12-26
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多