通过语句在组中获取特定值

时间:2019-04-24 06:02:55

标签: mysql sql

我有以下三行数据:

id       price          type
1        19.99          PERM
1        30.13          TEMP
2        14.44          SOME

我想按id分组并获得价格,并且曾经存在TEMP价格,请将其用作默认值。这是输出应为的示例:

id        price
1         30.13
2         14.44

到目前为止,我还停留在group by上:

SELECT 
GROUP_CONCAT(tp.price_value order by tp.price_type='temp' desc limit 1)
FROM prices GROUP BY id

我如何优先使用上述价格(order by, limit 1)?

我现在的两个想法是执行两个查询(一个联合似乎有点杀人了?!)或以一种编程语言对group_concat进行后处理。看起来都不是太理想,因此希望这里有一个更好,更简单的方法。

5 个答案:

答案 0 :(得分:3)

您可以将GROUP BYMAX一起使用以下解决方案:

SELECT id, IFNULL(maxTemp, maxOther) AS maxPrice
FROM (
    SELECT id,
        MAX(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) maxTemp, 
        MAX(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) maxOther
    FROM table_name
    GROUP BY id
)t;

此解决方案应为您提供符合要求的正确结果(ORDER BY ... DESC LIMIT 1


但是您也可以使用其他aggregate functions来获取SUM或价格值列表(使用GROUP_CONCAT)。

获取价格SUM的解决方案:

SELECT id, IFNULL(sumTemp, sumOther) AS sumPrice
FROM (
    SELECT id,
        SUM(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) sumTemp, 
        SUM(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) sumOther
    FROM table_name
    GROUP BY id
)t;

...或使用GROUP_CONCAT函数获取价格值列表:

SELECT id, IFNULL(gTemp, gOther) AS listPrice
FROM (
    SELECT id,
        GROUP_CONCAT(CASE WHEN type = 'TEMP' THEN price ELSE NULL END) gTemp, 
        GROUP_CONCAT(CASE WHEN type <> 'TEMP' THEN price ELSE NULL END) gOther
    FROM table_name
    GROUP BY id
)t;

demo on dbfiddle.uk

答案 1 :(得分:1)

您可以在ID为“ TEMP”的查询和ID为非“ TEMP”的查询之间使用联合

  select id, price
  from  my_table 
  where type ='TEMP'
  union 
  select id, max(price) 
  from my_table m1
  inner join (
  select id from my_table where id not in (
    selet id
    from my_table 
    where  type 'TEMP'
  ) 
  group by id 
  ) t1 on t1.id= m1.id 

答案 2 :(得分:0)

尝试使用联合和相关子查询,如下所示

  select id,max(price) as price from prices
  where type='temp' group by id
  union 
  select id,max(price) from prices t1
  where not exists( select 1 from prices t2 where t1.id=t2.id
                   and type='temp')
     group by id

由于您需要所有临时类型,因此第一个查询将获取所有临时输出,第二个查询将过滤所有临时组

online demo

输出

id  price
1   30.13
2   14.44

答案 3 :(得分:0)

这将起作用:

select * from(select a.id,a.type,
(select b.price from Table1  b where b.type=a.type and b.type in ('Temp')) mn
from Table1 a group by id,type)ab where mn is not null
union 
select id,type,max(price) from Table1
where type is not null 
and id not in(select id from(select a.id,a.type,
(select b.price from Table1  b where b.type=a.type and b.type in ('Temp')) mn
from Table1 a group by id,type)ab where mn is not null)
group by id,type;

检查http://sqlfiddle.com/#!9/c166a9/9

答案 4 :(得分:0)

这是迄今为止最棘手的方法(这里的其他两个答案是更正确的答案),但是您也可以使用CONCAT语句在字段本身之前进行排序。这是一个基本示例:

SELECT id, RIGHT(
    max(CONCAT(if(type='temp', 1,0), '^', price)),
    length(max(CONCAT(if(type='temp', 1,0), '^', price)))-2
) price FROM prices group by id

1   30.13
2   14.44

但是,由于它不依赖于子选择,因此可能会表现更好。