sql查询为每个项目获取具有最大出现次数的组的行

时间:2015-12-09 10:27:13

标签: sql sqlite

这个问题很难在标题中总结,所以这里有一个更详细的例子:

我拥有数千种不同物体的数十种测量数据。他们中的大多数都有相关的类型,但这种类型并不明确。

所以选择

SELECT oid, type, count(type) FROM data GROUP BY oid, type;

会产生类似的东西:

oid   type  count(type)
 0      0   22
 1      0   22
 2      1   61
 2      2  104
 3      2   63
 4      0   34
 6      0    1
 8      2   76
 9      0    1
11      3   33
12      0   55
13      4    1
13      5   28
13      1    2
13      2  255
14      4  148
14      1    4
14      2    3
15      3   10
16      0   13
18      4  137
18      1    5

如果这个唯一的行必须是具有最多出​​现次数的行,那么我如何只为每个对象获得一行?

奖金 - 问题:还会获得每个对象行的百分比,表示此类型的出现率。

结果如下:

oid   type  P(type)
 0      0   1.0
 1      0   1.0
 2      2   0.64
 3      2   1.0
 4      0   1.0
 6      0   1.0
 8      2   1.0
 9      0   1.0
11      3   1.0
12      0   1.0
13      2   0.89
14      4   0.95
15      3   1.0
16      0   1.0
18      4   0.96

编辑:

一些测试数据和一个解决方案几乎正确的输出:

http://pastebin.com/jVvHErJ2

2 个答案:

答案 0 :(得分:1)

此查询解决了您的两个问题

SELECT s.oid,
       s.type,
       s.total_per_oid_per_type,
       (s.total_per_oid_per_type + 0.0) / s.total_per_oid AS percentage
FROM (SELECT v.oid,
             v.type,
             v.total_per_oid_per_type,
             ROW_NUMBER() OVER (PARTITION BY v.oid ORDER BY v.total_per_oid_per_type DESC) AS object_number,
             SUM(v.total_per_oid_per_type) OVER (PARTITION BY v.oid) AS total_per_oid
      FROM (SELECT t.oid, t.type, count(1) AS total_per_oid_per_type
            FROM data t
            GROUP BY t.oid, t.type) v ) s
WHERE object_number = 1

Sqlite3专用解决方案(等于上述)

WITH v AS (
    SELECT oid,
           type,
           COUNT(1) AS total_per_oid_per_type
    FROM data
    GROUP BY oid, type
),
s AS (
    SELECT oid,
           MAX(total_per_oid_per_type) AS max_total_per_oid
    FROM v
    GROUP BY oid
),
totals AS (
    SELECT oid,
           SUM(total_per_oid_per_type) AS total_per_oid
    FROM v
    GROUP BY oid
)
SELECT v.oid,
       v.type,
       v.total_per_oid_per_type,
       (v.total_per_oid_per_type + 0.0) / totals.total_per_oid AS percentage
FROM v
     INNER JOIN s ON v.oid = s.oid AND v.total_per_oid_per_type = s.max_total_per_oid
     INNER JOIN totals ON v.oid = totals.oid
ORDER BY v.oid, v.type

答案 1 :(得分:0)

试试这个应该有效

create table ##TBL (oid INT, [type] INT, [count(type)] INT)
INSERT INTO ##TBL VALUES
(0,0,22),
(1,0,22),
(2,1,61),
(2,2,104),
(3,2,63),
(4,0,34),
(6,0,1),
(8,2,76),
(9,0,1),
(11,3,33),
(12,0,55),
(13,4,1),
(13,5,28),
(13,1,2),
(13,2,255),
(14,4,148),
(14,1,4),
(14,2,3),
(15,3,10),
(16,0,13),
(18,4,137),
(18,1,5)
--------------------------------

SELECT oid
      ,max([type]) as x
      --,Max([count(type)]) AS [count(type)]
      ,CAST( CAST( MAX([count(type)]) AS DECIMAL(10,2) ) /  CAST( SUM([count(type)]) AS DECIMAL(10,2) ) AS DECIMAL(10,2) ) AS 'Percent %'
from ##TBL
group by oid
相关问题