首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

SQL大于IN
EN

Stack Overflow用户
提问于 2015-08-03 12:24:28
回答 5查看 107关注 0票数 0

我使用Postgres 9.4并想做这样的事情:

代码语言:javascript
复制
movement_id|counter|standardized_output
---------------------------------------
1          |      3|                 10
1          |      3|                 12
1          |      5|                 10
2          |      4|                  5

我有以下查询:

代码语言:javascript
复制
SELECT movement_id, counter, MAX(standardized_output) AS standardized_output 
FROM "outputs" 
WHERE "outputs"."user_id" = 1 AND "outputs"."movement_id" IN (1,2) AND (counter in (1,3,5)) 
GROUP BY movement_id, counter

这给了我:

代码语言:javascript
复制
movement_id|counter|standardized_output
---------------------------------------
1          |      3|                 12
1          |      5|                 10

但是,我想要找到的是最大的(Standardized_output)是什么counter >= (1,3,5)。结果如下:

代码语言:javascript
复制
movement_id|counter|standardized_output
---------------------------------------
1          |      1|                 12 (MAX value where movement_id is 1 and counter is >=1)
1          |      3|                 12 (MAX value where movement_id is 1 and counter is >=3)
1          |      5|                 10 (MAX value where movement_id is 1 and counter is >=5)
2          |      1|                  5 (MAX value where movement_id is 2 and counter is >=1)
2          |      3|                  5 (MAX value where movement_id is 2 and counter is >=3)
2          |      5|               null (MAX value where movement_id is 2 and counter is >=5)

(小编辑: movement_id是IN,not =)

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-08-03 13:07:10

由于您希望对没有任何值的行产生结果,所以首先需要创建一个由应该存在的行组成的集合,在本例中是{movement_id} X {1,3,5}的笛卡尔积。为此,我们可以使用交叉连接和表值构造函数,然后使用左联接和子查询来获取最大值。

我相信这个查询是可以改进的,但是它应该能工作。

代码语言:javascript
复制
select 
    all_values.movement_id, 
    all_values.num, 
    (   
       select max(standardized_output) 
       from outputs 
       where counter >= all_values.num 
         and movement_id = all_values.movement_id
    ) as standardized_output 
from (
  select movement_id, t.num
  from outputs
  cross join (values (1), (3), (5)) as t(num) 
  where "movement_id" in (1 ,2)
-- and "outputs"."user_id" = 1 --this was missing in your sample so I left it commented out.
) all_values
left join outputs o on all_values.movement_id = o.movement_id
                   and (counter in (all_values.num)) 
group by all_values.movement_id, all_values.num
order by all_values.movement_id, all_values.num;

示例SQL Fiddle

给定您的示例数据,上面查询的结果是:

代码语言:javascript
复制
| movement_id | num | standardized_output |
|-------------|-----|---------------------|
|           1 |   1 |                  12 |
|           1 |   3 |                  12 |
|           1 |   5 |                  10 |
|           2 |   1 |                   5 |
|           2 |   3 |                   5 |
|           2 |   5 |              (null) |

编辑:使用此查询可以实现相同的结果:

代码语言:javascript
复制
select  
  o1.movement_id, 
  t.num as counter, 
  max(o2.standardized_output) as standardized_output
from outputs o1 cross join (values (1), (3), (5)) as t(num) 
left join outputs o2 on o1.movement_id = o2.movement_id and t.num <= o2.counter
where o1.movement_id in (1,2) 
group by o1.movement_id, t.num
order by o1.movement_id, t.num;

样品小提琴

票数 0
EN

Stack Overflow用户

发布于 2015-08-03 12:31:19

您可能会在计数器字段上放置一个CASE语句吗?

代码语言:javascript
复制
CASE WHEN counter >= 5 THEN 5
WHEN counter >=3 THEN 3
WHEN counter >=1 THEN 1
ELSE 0 END

然后将其添加到select和group子句中。

代码语言:javascript
复制
SELECT movement_id,
    (CASE WHEN counter >= 5 THEN 5
      WHEN counter >=3 THEN 3
      WHEN counter >=1 THEN 1
      ELSE 0 END) as new_counter,
    MAX(standardized_output) AS standardized_output 
FROM "outputs" 
WHERE "outputs"."user_id" = 1 AND "outputs"."movement_id" = 1
GROUP BY movement_id,
    (CASE WHEN counter >= 5 THEN 5
      WHEN counter >=3 THEN 3
      WHEN counter >=1 THEN 1
      ELSE 0 END)
票数 0
EN

Stack Overflow用户

发布于 2015-08-03 12:38:19

我正要在行中发布一些关于Kez所做的事情(使用case语句),但有点不同。

我不知道在这里你需要哪些条件,我不知道计数器>= (1,3,5)是否可以被翻译成>= 5?在下面的示例中,我认为计数器>= (1, 3,5 )是指计数器>= 5(问题是如何理解这里的分号--如果要将它们转换为ANDs或or ),我使用了>=,因此计数器>= (1,3,5)与计数器>=5相同,但如果分号被理解为or,则表示您感兴趣的计数器值2或4)。

无论如何,对于不想在max函数中考虑标准化输出的任何条件,请将它们包含在情况条件中,并使计数器返回零,因此它不会影响您的最大值(如果需要,也不影响负数)。

代码语言:javascript
复制
SELECT 
       movement_id,
       counter,
       MAX(CASE WHEN COUNTER < 1 THEN 0 ELSE COUNTER END ) AS standardized_output
  FROM outputs
 WHERE
   outputs.user_id = 1
   AND outputs.movement_id = 1
   AND counter in (1, 3, 5)
 GROUP BY movement_id, counter
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31787205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档