SQL DISTINCT EXISTS GROUP BY聚合函数

时间:2016-03-24 04:12:51

标签: mysql sql group-by

是否存在具有GROUP BY聚合函数的关系数据库,如DISTINCT EXISTS,如果该组有多个不同的值,则返回TRUE,否则为FALSE?我正在寻找能够遍历组中值的东西,直到当前值与前一个值不同,而不是计算所有不同的值。

Example:
pv_name | time_stamp | value
A       | 1          | 1
B       | 2          | 1
C       | 3          | 1
A       | 4          | 2
C       | 5          | 2
B       | 6          | 3

SELECT pv_name
FROM example
WHERE time_stamp > 0 AND time_stamp < 6
GROUP BY pv_name
HAVING DISTINCT_EXISTS(value);

Result: A, C

3 个答案:

答案 0 :(得分:1)

SELECT pv_name
FROM example
WHERE time_stamp > 0 AND time_stamp < 6
GROUP BY pv_name
HAVING MIN(value)<>MAX(value);

根据索引,可以更快地到达那里。我认为你不会比这更好或COUNT(DISTINCT value)

您是否尝试过两次加入示例? Psuedo-code示例:

with
(
    SELECT pv_name
    FROM example
    WHERE time_stamp > 0 AND time_stamp < 6
) as Q
select distinct Q1.pv_name
from Q as Q1 inner join Q as Q2 on
Q1.pv_name=Q2.pv_name and
Q1.value<>q2.value

答案 1 :(得分:0)

你可能知道COUNT(DISTINCT)函数,你想避免它来防止不必要的计算。

很难知道为什么要这样做,但我认为使用最明显的查询需要很长时间才能找到这些组:

SELECT type, COUNT(DISTINCT product)
FROM aTable
GROUP BY type
HAVING COUNT(DISTINCT product) > 1

我建议你试试窗口功能。试试新的T-SQL LAST_VALUE和FIRST_VALUE函数:

with c as (
SELECT type
 ,LAST_VALUE(product) OVER (PARTITION BY type ORDER BY product) lv
 ,FIRST_VALUE(product) OVER (PARTITION BY type ORDER BY product) pv
FROM aTable
)
SELECT * from c where lv <> pv

如果数据库引擎足够智能,它将找到该组的第一个/最后一个值,并且不会尝试计算所有值,因此效果更好。

对于MySQL,您可以使用辅助变量根据不同的值获取每组的row_number,如下所示:

SELECT type, product
FROM (
SELECT  @row_num := IF(@prev_type=type and @prev_prod=product,@row_num+1,1) AS RowNumber
       ,type
       ,product
       ,@prev_type := type
       ,@prev_prod := product
  FROM Person,
      (SELECT @row_num := 1) x,
      (SELECT @prev_type := '') y,
      (SELECT @prev_prod := '') z
  ORDER BY type, product
) as a
WHERE RowNumber > 1

答案 2 :(得分:0)

我认为having min (value) <> max (value)在这里效率最高。另一种选择是:

 Select distinct pv_name
 From example e
 Left join (
     Select value
     From example
     Where ...
     Group by value
     Having count (*) = 1
     ) s on e.value = s.value
 Where s.value is null

或者您可以使用NOT EXISTS代替该子查询。

在子查询中包含相关的where子句。

相关问题