使用分组依据无法存储值?

时间:2019-02-03 22:30:24

标签: sql postgresql

我有一个看起来像这样的表:

Field A | Field B | Field C | Field D | Field E | Field F
100001  |  10.00  | 2.00   | -1.00. | 7.00   | "0-9.99
100002  |  8.00   | 1.00   | NULL   | 7.00   | "1-9.99"
100003  |  40.00  | 2.00.  | NULL   | 38.00  | "30.00-39.99"
100004  |  20.00  | 1.00.  | NULL   | 19.00  | "10 - 19.99"
100005  |  30.00  | 11.00  | NULL   | 19.00. | "10 - 19.99"

字段E是字段B,C和D的总和-我已经知道了,这是我的代码

现在,我想创建一个计算字段Field F,该字段根据字段E中的值进行存储。例如,第一行将在0-9.99之间,但我不知道如何执行此操作。

理想情况下,我想在一个查询中完成全部操作。并且特定的语法是PostgreSQL,但是该特定的应用程序不能很好地运行。即使SELECT * FROM Table1;也会引发错误。这可能是由于我相对缺乏该语法的经验,但也许你们可以告诉我如何解决此查询。这是我到目前为止尝试过的

  SELECT "Field A,"Field B","Field C","Field D",
  (coalesce("FIELD B", 0) - coalesce("Field C", 0) + 
  coalesce("Field D", 0)) AS "Field E" 
  From "Table1";SELECT "Field E",CASE WHEN “Field D” >= 0 and 
  “FIELD D” <= 9.99 then “0-9.99”
     WHEN “FIELD D” >= 10 and “FIELD D” <= 19.99 then “10 to 19.99”
     WHEN “Field D” >= 20 and “Field D” <= 29.99 then “20 to 29.99”
     WHEN “Field D” >= 30 and “Field D” <= 39.99 then “30 to 39.99”
     WHEN “Field D” >= 40 and “Field D” <= 49.99 then “40 to 49.99”
     ELSE “$50+”
     END FROM “Orders”;

我实际上只是想根据字段E(另一个计算字段)的值在其中选择字段F中的存储区的列。我所有的常规查询都无法在该特定应用程序中正常工作,而我只是想看看我是否缺少一些愚蠢的东西。谢谢。

4 个答案:

答案 0 :(得分:1)

从50开始,然后移至较低的值:

case 
  when fieldE >= 50 then '$50+'
  when fieldE >= 40 then '40-49.99'
  when fieldE >= 30 then '30-39.99'
  when fieldE >= 20 then '20-29.99'
  when fieldE >= 10 then '10-19.99'
  when fieldE >= 0 then '0-9.99'
  else ''
end

答案 1 :(得分:0)

首先,即使使用示例数据,带空格的列名称几乎总是一个坏主意。一些SQL引擎更喜欢在列名周围使用“单引号”,而不是“双精度”。

您可以嵌套查询以首先获取所有预计算,然后在装入存储桶时进行处理。内部查询来自应用计算的Table1(t1别名)。该结果将成为别名“ PQ”(预查询),并通过现在可用的“ FieldE”列简化您的案例/时间。

select
      PQ.FieldA,
      PQ.FieldB,
      PQ.FieldC,
      PQ.FieldD,
      PQ.FieldE,
      case when PQ.FieldE < 10 then '0 - 9.99'
           when PQ.FieldE >= 10 AND PQ.FieldE < 20 then '10 to 19.99'
           when PQ.FieldE >= 20 and PQ.FieldE < 30 then '20 to 29.99'
           when PQ.FieldE >= 30 and PQ.FieldE < 40 then '30 to 39.99'
           when PQ.FieldE >= 40 and PQ.FieldE < 50 then '40 to 49.99'
           else '$50+' end CalcBucket
   from
      ( SELECT
              T1.FieldA,
              T1.FieldB,
              T1.FieldC,
              T1.FieldD,
              coalesce( T1.FieldB, 0) 
               - coalesce(T1.FieldC, 0) 
               + coalesce(T1.FieldD, 0)) AS FieldE 
           From 
              T1 )  PQ

答案 2 :(得分:0)

是的,您有语法错误,并且case语句基于D而不基于E。请尝试以下操作:

WITH tmp AS (
    SELECT 
        "Field A",
        "Field B",
        "Field C",
        "Field D",
        (coalesce("FIELD B", 0) - coalesce("Field C", 0) +  coalesce("Field D", 0)) AS "Field E"
    FROM "Table1"
)
SELECT 
    tmp.*, 
    CASE 
        WHEN "Field E" >=  0 and "FIELD E" <=  9.99 THEN "0-9.99"
        WHEN "FIELD E" >= 10 and "FIELD E" <= 19.99 THEN "10 to 19.99"
        WHEN "Field E" >= 20 and "Field E" <= 29.99 THEN "20 to 29.99"
        WHEN "Field E" >= 30 and "Field E" <= 39.99 THEN "30 to 39.99"
        WHEN "Field E" >= 40 and "Field E" <= 49.99 THEN "40 to 49.99"
        ELSE "$50+"
    END AS "Field F"
FROM 
    tmp

答案 3 :(得分:0)

您可以使用width_bucket 找到适合的存储桶field_e,从而避免写出可能很长的CASE语句:

WITH tmp AS (
    SELECT * FROM (VALUES 
    (100001  ,  10.00  , 2.00  , -1.00 ),
    (100002  ,  8.00   , 1.00  , NULL  ),
    (100003  ,  40.00  , 2.00  , NULL  ),
    (100004  ,  20.00  , 1.00  , NULL  ),
    (100005  ,  30.00  , 11.00 , NULL  )
    ) foo (field_a , field_b , field_c , field_d)
    ), cutoffs AS (
    SELECT idx, cutoff::text || '-' || COALESCE(next_cutoff::text, '+') AS label
    FROM (
        SELECT 
            ROW_NUMBER() OVER (ORDER BY cutoff) AS idx, 
            cutoff, 
            LEAD(cutoff) OVER (ORDER BY cutoff) - 0.01 AS next_cutoff
        FROM generate_series(0, 50, 10) AS cutoff) t )
SELECT field_a , field_b , field_c , field_d, field_e, label AS field_f
FROM (
    SELECT *, width_bucket(field_e, 0, 50, 5) AS idx
    FROM (
        SELECT *, COALESCE(field_b, 0) - COALESCE(field_c, 0) + COALESCE(field_d, 0) AS field_e
        FROM tmp) t1
    ) t2
INNER JOIN cutoffs
USING (idx)
ORDER BY field_a

收益

| field_a | field_b | field_c | field_d | field_e |  field_f |
|---------+---------+---------+---------+---------+----------|
|  100001 |   10.00 |    2.00 |   -1.00 |    7.00 |   0-9.99 |
|  100002 |    8.00 |    1.00 |         |    7.00 |   0-9.99 |
|  100003 |   40.00 |    2.00 |         |   38.00 | 30-39.99 |
|  100004 |   20.00 |    1.00 |         |   19.00 | 10-19.99 |
|  100005 |   30.00 |   11.00 |         |   19.00 | 10-19.99 |