计算列中不同的出现次数

时间:2014-03-26 12:57:27

标签: mysql

我希望能够选择Somedata_A和Somedata_B列中的数据从其列中的上一行更改的次数。我尝试过使用DISTINCT,但它在某种程度上有效。 {1,2,3,2,1,1}将显示3,当我希望它显示4个过程时,按顺序排列5个不同的值。

示例:

 A,B,C,D,E,F
{1,2,3,2,1,1}

AB相比有所不同,BC相比有所不同。 。 。与E相比,F没有区别。总而言之,它在一组6个值中给出了4个差异。

我已经DISTINCT开始工作,但它对我来说并不是真的有用。为了增加问题,我对整个范围真的不感兴趣,让我们说每个标题的最后两天/条目。

其次我关注性能问题。我在下面的查询中尝试了一组真实的数据,并且可能因超时而中断了。

SQL Fiddle

MySQL 5.5.32架构设置

CREATE TABLE testdata(
Title varchar(10),
Date varchar(10),
Somedata_A int(5),
Somedata_B int(5));


INSERT INTO testdata (Title, Date, Somedata_A, Somedata_B) VALUES
("Alpha", '123', 1, 2), 
("Alpha", '234', 2, 2), 
("Alpha", '345', 1, 2),
("Alpha", '349', 1, 2), 
("Alpha", '456', 1, 2), 
("Omega", '123', 1, 1), 
("Omega", '234', 2, 2), 
("Omega", '345', 3, 3),
("Omega", '349', 4, 3), 
("Omega", '456', 5, 4),
("Delta", '123', 1, 1), 
("Delta", '234', 2, 2), 
("Delta", '345', 1, 3),
("Delta", '349', 2, 3), 
("Delta", '456', 1, 4);

查询1

SELECT t.Title, (SELECT COUNT(DISTINCT Somedata_A) FROM testdata AS tt WHERE t.Title = tt.Title) AS A,
    (SELECT COUNT(DISTINCT Somedata_B) FROM testdata AS tt WHERE t.Title = tt.Title) AS B
    FROM testdata AS t
    GROUP BY t.Title

Results

| TITLE | A | B |
|-------|---|---|
| Alpha | 2 | 1 |
| Delta | 2 | 4 |
| Omega | 5 | 4 |

2 个答案:

答案 0 :(得分:1)

这样的东西可能有效:它使用变量表示行号,连接偏移量为1,然后计算A和B的差异。

http://sqlfiddle.com/#!2/3bbc8/9/2

set @i = 0;
set @j = 0;

Select 
A.Title aTitle, 
sum(Case when A.SomeData_A <> B.SomeData_A then 1 else 0 end) AVar, 
sum(Case when A.SomeData_B <> B.SomeData_B then 1 else 0 end) BVar
from 
(SELECT Title, @i:=@i+1 as ROWID, SomeData_A, SomeData_B 
FROM testdata
ORDER BY Title, date desc) as A
INNER JOIN 
(SELECT Title, @j:=@j+1 as ROWID, SomeData_A, SomeData_B
FROM testdata
ORDER BY Title, date desc) as B
 ON A.RowID= B.RowID + 1
 AND A.Title=B.Title
Group by A.Title

答案 1 :(得分:0)

这有效(见here)(仅供参考:您在问题中的结果与您的数据不匹配 - 例如,对于Alpha,ColumnA:它永远不会从1更改。答案应为0)

希望您可以将此声明调整为您的实际数据模型

SELECT t1.title, SUM(t1.Somedata_A<>t2.Somedata_a) as SomeData_A
  ,SUM(t1.Somedata_b<>t2.Somedata_b) as SomeData_B
FROM testdata AS t1
JOIN testdata AS t2
  ON t1.title = t2.title
    AND t2.date = DATE_ADD(t1.date, INTERVAL 1 DAY)
GROUP BY t1.title
ORDER BY t1.title;