Hướng dẫn mysql median - trung bình mysql

Tôi đang sử dụng bảng dưới đây cho giải pháp trong MySQL:

CREATE TABLE transactions (
  transaction_id int , user_id int , merchant_name varchar(255), transaction_date date , amount int
);

INSERT INTO transactions (transaction_id, user_id, merchant_name, transaction_date, amount)  
VALUES (1, 1 ,'abc', '2015-08-17', 100),(2, 2, 'ced', '2015-2-17', 100),(3, 1, 'def', '2015-2-16', 121),
(4, 1 ,'ced', '2015-3-17', 110),(5, 1, 'ced', '2015-3-17', 150),(6, 2 ,'abc', '2015-4-17', 130), 
(7, 3 ,'ced', '2015-12-17', 10),(8, 3 ,'abc', '2015-8-17', 100),(9, 2 ,'abc', '2015-12-17', 140),(10, 1,'abc', '2015-9-17', 100),
(11, 1 ,'abc', '2015-08-17', 121),(12, 2 ,'ced', '2015-12-23', 130),(13, 1 ,'def', '2015-12-23', 13),(3, 4, 'abc', '2015-2-16', 120),(3, 4, 'def', '2015-2-16', 121),(3, 4, 'ced', '2015-2-16', 121);

Tính toán trung bình cho cột 'số tiền':

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;

TotalRecords = 16 và trung bình = 120,5000

Truy vấn này sẽ hoạt động cho cả hai điều kiện, tức là các bản ghi chẵn và lẻ.

Tôi có một cơ sở dữ liệu chứa khoảng 1 tỷ hàng mà chúng tôi yêu cầu để xác định tuổi trung bình trong tập hợp. Sắp xếp một tỷ hàng là khó, nhưng nếu bạn tổng hợp các giá trị riêng biệt có thể tìm thấy (độ tuổi từ 0 đến 100), bạn có thể sắp xếp danh sách này và sử dụng một số phép thuật số học để tìm bất kỳ phần trăm nào bạn muốn như sau:

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;

Truy vấn này phụ thuộc vào các chức năng cửa sổ hỗ trợ DB của bạn (bao gồm cả các hàng không bị ràng buộc trước đó) nhưng nếu bạn không có vấn đề đơn giản là tham gia CTE AGGDATA với chính nó và tổng hợp tất cả các tổng số trước đó vào cột 'tích lũy' để xác định cái nào Giá trị chứa tiền lệ được chỉ định. Mẫu trên tính toán P10, P25, P50 (trung bình), p75 và p90.

-Chris

Đã trả lời ngày 17 tháng 6 năm 2015 lúc 4:53Jun 17, 2015 at 4:53

Chris Knollchris KnollChris Knoll

3912 Huy hiệu bạc13 Huy hiệu đồng2 silver badges13 bronze badges

Lấy từ: http://mdb-blog.blogspot.com/2015/06/mysql-find-median-nth-ement-without.html

Tôi sẽ đề xuất một cách khác, không cần tham gia, nhưng làm việc với các chuỗiwithout join, but working with strings

Tôi đã không kiểm tra nó với các bảng có dữ liệu lớn, nhưng các bảng nhỏ/vừa, nó hoạt động tốt.

Điều tốt ở đây, nó cũng hoạt động bằng cách nhóm để nó có thể trả về trung bình cho một số mặt hàng.by GROUPING so it can return the median for several items.

Dưới đây là mã kiểm tra cho bảng kiểm tra:

DROP TABLE test.test_median
CREATE TABLE test.test_median AS
SELECT 'book' AS grp, 4 AS val UNION ALL
SELECT 'book', 7 UNION ALL
SELECT 'book', 2 UNION ALL
SELECT 'book', 2 UNION ALL
SELECT 'book', 9 UNION ALL
SELECT 'book', 8 UNION ALL
SELECT 'book', 3 UNION ALL

SELECT 'note', 11 UNION ALL

SELECT 'bike', 22 UNION ALL
SELECT 'bike', 26 

và mã để tìm trung vị cho mỗi nhóm:

SELECT grp,
         SUBSTRING_INDEX( SUBSTRING_INDEX( GROUP_CONCAT(val ORDER BY val), ',', COUNT(*)/2 ), ',', -1) as the_median,
         GROUP_CONCAT(val ORDER BY val) as all_vals_for_debug
FROM test.test_median
GROUP BY grp

Output:

grp | the_median| all_vals_for_debug
bike| 22        | 22,26
book| 4         | 2,2,3,4,7,8,9
note| 11        | 11

Đã trả lời ngày 19 tháng 6 năm 2015 lúc 12:03Jun 19, 2015 at 12:03

Hướng dẫn mysql median - trung bình mysql

mr.baby123mr.baby123mr.baby123

2.12022 Huy hiệu bạc12 Huy hiệu đồng22 silver badges12 bronze badges

1

Trong một số trường hợp, trung bình được tính như sau:

"Trung bình" là giá trị "giữa" trong danh sách các số khi chúng được đặt hàng theo giá trị. Đối với các bộ đếm thậm chí, trung bình là trung bình của hai giá trị trung bình. Tôi đã tạo một mã đơn giản cho điều đó:median is average of the two middle values. I've created a simple code for that :

$midValue = 0;
$rowCount = "SELECT count(*) as count {$from} {$where}";

$even = FALSE;
$offset = 1;
$medianRow = floor($rowCount / 2);
if ($rowCount % 2 == 0 && !empty($medianRow)) {
  $even = TRUE;
  $offset++;
  $medianRow--;
}

$medianValue = "SELECT column as median 
               {$fromClause} {$whereClause} 
               ORDER BY median 
               LIMIT {$medianRow},{$offset}";

$medianValDAO = db_query($medianValue);
while ($medianValDAO->fetch()) {
  if ($even) {
    $midValue = $midValue + $medianValDAO->median;
  }
  else {
    $median = $medianValDAO->median;
  }
}
if ($even) {
  $median = $midValue / 2;
}
return $median;

$ Trung bình trả về sẽ là kết quả cần thiết :-)

Đã trả lời ngày 15 tháng 7 năm 2015 lúc 10:54Jul 15, 2015 at 10:54

Hướng dẫn mysql median - trung bình mysql

jitendrapurohitjitendrapurohitjitendrapurohit

9.1792 Huy hiệu vàng26 Huy hiệu bạc38 Huy hiệu Đồng2 gold badges26 silver badges38 bronze badges

Trung bình được nhóm theo chiều:

SELECT your_dimension, avg(t1.val) as median_val FROM (
SELECT @rownum:=@rownum+1 AS `row_number`,
   IF(@dim <> d.your_dimension, @rownum := 0, NULL),
   @dim := d.your_dimension AS your_dimension,
   d.val
   FROM data d,  (SELECT @rownum:=0) r, (SELECT @dim := 'something_unreal') d
  WHERE 1
  -- put some where clause here
  ORDER BY d.your_dimension, d.val
) as t1
INNER JOIN  
(
  SELECT d.your_dimension,
    count(*) as total_rows
  FROM data d
  WHERE 1
  -- put same where clause here
  GROUP BY d.your_dimension
) as t2 USING(your_dimension)
WHERE 1
AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) )

GROUP BY your_dimension;

Đã trả lời ngày 4 tháng 8 năm 2015 lúc 16:18Aug 4, 2015 at 16:18

Hướng dẫn mysql median - trung bình mysql

0

Cách này dường như bao gồm cả số đồng đều và số lẻ mà không cần phụ.

SELECT AVG(t1.x)
FROM table t1, table t2
GROUP BY t1.x
HAVING SUM(SIGN(t1.x - t2.x)) = 0

Đã trả lời ngày 1 tháng 11 năm 2016 lúc 4:18Nov 1, 2016 at 4:18

Hướng dẫn mysql median - trung bình mysql

Yuhanluoyuhanluoyuhanluo

191 Huy hiệu bạc6 Huy hiệu đồng1 silver badge6 bronze badges

2

Các phương pháp này chọn từ cùng một bảng hai lần. Nếu dữ liệu nguồn đến từ một truy vấn đắt tiền, đây là một cách để tránh chạy nó hai lần:

select KEY_FIELD, AVG(VALUE_FIELD) MEDIAN_VALUE
from (
    select KEY_FIELD, VALUE_FIELD, RANKF
    , @rownumr := IF(@prevrowidr=KEY_FIELD,@rownumr+1,1) RANKR
    , @prevrowidr := KEY_FIELD
    FROM (
        SELECT KEY_FIELD, VALUE_FIELD, RANKF
        FROM (
            SELECT KEY_FIELD, VALUE_FIELD 
            , @rownumf := IF(@prevrowidf=KEY_FIELD,@rownumf+1,1) RANKF
            , @prevrowidf := KEY_FIELD     
            FROM (
                SELECT KEY_FIELD, VALUE_FIELD 
                FROM (
                    -- some expensive query
                )   B
                ORDER BY  KEY_FIELD, VALUE_FIELD
            ) C
            , (SELECT @rownumf := 1) t_rownum
            , (SELECT @prevrowidf := '*') t_previd
        ) D
        ORDER BY  KEY_FIELD, RANKF DESC
    ) E
    , (SELECT @rownumr := 1) t_rownum
    , (SELECT @prevrowidr := '*') t_previd
) F
WHERE RANKF-RANKR BETWEEN -1 and 1
GROUP BY KEY_FIELD

Đã trả lời ngày 8 tháng 12 năm 2016 lúc 11:17Dec 8, 2016 at 11:17

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
0

HOẶC

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
1

Đã trả lời ngày 5 tháng 3 năm 2017 lúc 1:12Mar 5, 2017 at 1:12

Mã SQL sau đây sẽ giúp bạn tính toán trung bình trong MySQL bằng các biến do người dùng xác định.

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
2

Nếu bạn đang tìm kiếm giải thích chi tiết, xin vui lòng tham khảo blog này.

Đã trả lời ngày 5 tháng 10 năm 2017 lúc 5:53Oct 5, 2017 at 5:53

Truy vấn dưới đây sẽ hoạt động hoàn hảo cho cả số hàng chẵn hoặc số lẻ. Trong truy vấn con, chúng tôi đang tìm (các) giá trị có cùng số lượng hàng trước và sau nó. Trong trường hợp các hàng lẻ, mệnh đề có sẽ đánh giá thành 0 (cùng số lượng hàng trước và sau khi hủy bỏ dấu hiệu).

Tương tự, đối với các hàng thậm chí, mệnh đề có đánh giá thành 1 cho hai hàng (các hàng trung tâm 2) vì chúng sẽ (tập thể) có cùng số lượng hàng trước và sau.

Trong truy vấn bên ngoài, chúng tôi sẽ tìm ra giá trị đơn (trong trường hợp các hàng lẻ) hoặc (2 giá trị trong trường hợp các hàng chẵn).

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
3

LƯU Ý: Trong trường hợp bảng của bạn có các giá trị trùng lặp, nên điều khoản có ở trên nên được thay đổi thành điều kiện bên dưới. Trong trường hợp này, có thể có các giá trị bên ngoài các khả năng ban đầu là 0,1. Điều kiện dưới đây sẽ làm cho điều kiện này động và hoạt động trong trường hợp trùng lặp.

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
4

Đã trả lời ngày 7 tháng 11 năm 2020 lúc 18:14Nov 7, 2020 at 18:14

Thử một cái gì đó như:

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
5

**

Lưu ý: Lý do cho -1 là để làm cho nó không được lập chỉ mục..i.e số hàng hiện bắt đầu từ 0 thay vì 1

**

Lưu ý: Lý do cho -1 là để làm cho nó không được lập chỉ mục..i.e số hàng hiện bắt đầu từ 0 thay vì 1Jan 18, 2021 at 10:08

Hướng dẫn mysql median - trung bình mysql

Đã trả lời ngày 18 tháng 1 năm 2021 lúc 10:08

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
6

Tôi đã không so sánh hiệu suất của giải pháp này với phần còn lại của các câu trả lời được đăng ở đây, nhưng tôi thấy đây là cách thẳng thắn nhất để hiểu, và bao gồm toàn bộ phạm vi của công thức toán học để tính toán trung bình. Nói cách khác, giải pháp này sẽ đủ mạnh mẽ cho các bộ dữ liệu được đánh số chẵn và lẻ:May 31, 2021 at 2:30

Hướng dẫn mysql median - trung bình mysql

Đã trả lời ngày 31 tháng 5 năm 2021 lúc 2:30

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
7

Đã trả lời ngày 6 tháng 6 năm 2021 lúc 6:26Jun 6, 2021 at 6:26

Hướng dẫn mysql median - trung bình mysql

SudhanshusudhanshuSudhanshu

6148 Huy hiệu bạc22 Huy hiệu đồng8 silver badges22 bronze badges

Nếu đây là MySQL, bây giờ có các chức năng cửa sổ và bạn có thể thực hiện theo cách này (giả sử bạn muốn làm tròn đến số nguyên gần nhất - nếu không chỉ cần thay thế

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
3 bằng
with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
4 hoặc
with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
5 hoặc bạn có gì). Giải pháp sau đây hoạt động cho các bảng bất kể chúng có số lượng hàng chẵn hay số lượng hàng lẻ:

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
8

Tôi nghĩ rằng một số câu trả lời gần đây hơn về chủ đề này đã nhận được ở cách tiếp cận này, nhưng có vẻ như mọi người đã suy nghĩ quá mức, vì vậy hãy xem đây là một phiên bản cải tiến. Bất kể hương vị SQL là gì, không có lý do gì ai đó nên viết một đoạn mã khổng lồ với nhiều nhóm con chỉ để có được trung bình vào năm 2021. Tuy nhiên, xin lưu ý rằng truy vấn ở trên chỉ hoạt động nếu bạn được yêu cầu tìm trung vị cho một loạt liên tục. Tất nhiên, bất kể số lượng hàng, đôi khi mọi người tạo ra sự khác biệt giữa những gì được gọi là trung bình riêng biệt và những gì được gọi là trung bình nội suy cho một chuỗi liên tục.continuous series. Of course, regardless of row number, sometimes people do make a distinction between what is referred to as the Discrete Median and what is referred to as the Interpolated Median for a continuous series.

Nếu bạn được yêu cầu tìm trung bình cho một chuỗi riêng biệt và bảng có số lượng hàng chẵn, giải pháp trên sẽ không hoạt động với bạn và bạn nên hoàn nguyên sử dụng một trong các giải pháp khác, như Thejacobtaylor.discrete series and the table has an even number of rows, the above solution will not work for you, and you should revert to using one of the other solutions, like TheJacobTaylor's.

Giải pháp thứ hai dưới đây là phiên bản được sửa đổi một chút của Thejacobtaylor, nơi tôi nêu rõ

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
6. Điều này cũng sẽ hoạt động cho các bảng có số lượng hàng kỳ lạ, bất kể bạn có được yêu cầu tìm trung vị cho một chuỗi liên tục hay riêng biệt hay không, nhưng tôi sẽ sử dụng cụ thể nó khi được yêu cầu tìm trung vị của một chuỗi rời rạc. Nếu không, sử dụng giải pháp đầu tiên. Bằng cách đó, bạn sẽ không bao giờ phải suy nghĩ về việc dữ liệu có chứa số lượng dữ liệu 'chẵn' hay 'lẻ' hay không.

WITH Numbered AS 
(
SELECT *, COUNT(*) OVER () AS TotatRecords,
    ROW_NUMBER() OVER (ORDER BY amount) AS RowNum
FROM transactions
)
SELECT Avg(amount)
FROM Numbered
WHERE RowNum IN ( FLOOR((TotatRecords+1)/2), FLOOR((TotatRecords+2)/2) )
;
9

Cuối cùng, bạn có thể dễ dàng thực hiện điều này trong PostgreSQL bằng cách sử dụng các chức năng tích hợp. Dưới đây là một lời giải thích tốt đẹp, cùng với một bản tóm tắt hiệu quả về các trung vị nội suy riêng biệt.

https://leafo.net/guides/postgresql-calculating-percentile.html#calculating-the-median

Đã trả lời ngày 20 tháng 6 năm 2021 lúc 19:38Jun 20, 2021 at 19:38

Đối với một trạm bảng và cột lat_n, đây là mã MySQL để có được trung bình:

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
0

Đã trả lời ngày 23 tháng 9 năm 2021 lúc 12:46Sep 23, 2021 at 12:46

Bạn có thể sử dụng hàm window row_number () để trả lời truy vấn để tìm phương tiện

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
1

Đã trả lời ngày 23 tháng 2 lúc 20:15Feb 23 at 20:15

Hướng dẫn mysql median - trung bình mysql

with rawData(count_value) as
(
    select p.YEAR_OF_BIRTH
        from dbo.PERSON p
),
overallStats (avg_value, stdev_value, min_value, max_value, total) as
(
  select avg(1.0 * count_value) as avg_value,
    stdev(count_value) as stdev_value,
    min(count_value) as min_value,
    max(count_value) as max_value,
    count(*) as total
  from rawData
),
aggData (count_value, total, accumulated) as
(
  select count_value, 
    count(*) as total, 
        SUM(count(*)) OVER (ORDER BY count_value ROWS UNBOUNDED PRECEDING) as accumulated
  FROM rawData
  group by count_value
)
select o.total as count_value,
  o.min_value,
    o.max_value,
    o.avg_value,
    o.stdev_value,
    MIN(case when d.accumulated >= .50 * o.total then count_value else o.max_value end) as median_value,
    MIN(case when d.accumulated >= .10 * o.total then count_value else o.max_value end) as p10_value,
    MIN(case when d.accumulated >= .25 * o.total then count_value else o.max_value end) as p25_value,
    MIN(case when d.accumulated >= .75 * o.total then count_value else o.max_value end) as p75_value,
    MIN(case when d.accumulated >= .90 * o.total then count_value else o.max_value end) as p90_value
from aggData d
cross apply overallStats o
GROUP BY o.total, o.min_value, o.max_value, o.avg_value, o.stdev_value
;
2

Hướng dẫn mysql median - trung bình mysql

Fabich

2.5563 huy hiệu vàng28 Huy hiệu bạc40 Huy hiệu đồng3 gold badges28 silver badges40 bronze badges

Đã trả lời ngày 25 tháng 6 năm 2016 lúc 10:59Jun 25, 2016 at 10:59

0