Tôi có một loạt giá trị trong cơ sở dữ liệu mà tôi cần kéo để tạo biểu đồ đường. Vì tôi không yêu cầu độ phân giải cao nên tôi muốn lấy mẫu lại dữ liệu bằng cách chọn mọi hàng thứ 5 từ cơ sở dữ liệu.
Tôi có một loạt giá trị trong cơ sở dữ liệu mà tôi cần kéo để tạo biểu đồ đường. Vì tôi không yêu cầu độ phân giải cao nên tôi muốn lấy mẫu lại dữ liệu bằng cách chọn mọi hàng thứ 5 từ cơ sở dữ liệu.
Câu trả lời:
SELECT *
FROM (
SELECT
@row := @row +1 AS rownum, [column name]
FROM (
SELECT @row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
[n]
trong truy vấn bằng 5 để nhận mỗi hàng thứ 5.
@row :=0
với@row :=2
= 1
thành= 2
Bạn có thể thử mod 5 để lấy các hàng có ID là bội số của 5. (Giả sử bạn có một số loại cột ID tuần tự.)
select * from table where table.id mod 5 = 0;
Vì bạn đã nói rằng bạn đang sử dụng MySQL, bạn có thể sử dụng các biến người dùng để tạo đánh số hàng liên tục. Tuy nhiên, bạn phải đặt nó trong một bảng dẫn xuất (truy vấn con).
SET @x := 0;
SELECT *
FROM (SELECT (@x:=@x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t
WHERE x MOD 5 = 0;
Tôi đã thêm ORDER BY RAND()
để lấy mẫu ngẫu nhiên, thay vì cho phép mọi hàng thứ năm của bảng không có thứ tự đều có trong mẫu mỗi lần.
Một người dùng ẩn danh đã cố gắng chỉnh sửa điều này để thay đổi x MOD 5 = 0
thành x MOD 5 = 1
. Tôi đã thay đổi nó trở lại ban đầu của tôi.
Đối với bản ghi, người ta có thể sử dụng bất kỳ giá trị nào từ 0 đến 4 trong điều kiện đó và không có lý do gì để thích giá trị này hơn giá trị khác.
SET @a = 0;
SELECT * FROM t where (@a := @a + 1) % 2 = 0;
Tôi đã tìm kiếm một cái gì đó như thế này. Câu trả lời của Taylor và Bill đã khiến tôi cải thiện ý tưởng của họ.
table data1 có các trường read_date, giá trị mà chúng ta muốn chọn mỗi bản ghi 2d từ một truy vấn giới hạn bởi phạm vi read_date, tên của bảng dẫn xuất là tùy ý và ở đây được gọi là DT
truy vấn:
SET @row := 0;
SELECT * FROM ( SELECT @row := @row +1 AS rownum, read_date, value FROM data1
WHERE read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0
SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime > now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
Bạn có thể sử dụng truy vấn này,
set @n=2; <!-- nth row -->
select * from (SELECT t.*,
@rowid := @rowid + 1 AS ID
FROM TABLE t,
(SELECT @rowid := 0) dummy) A where A.ID mod @n = 0;
hoặc bạn có thể thay thế n bằng giá trị thứ n của bạn
Nếu bạn đang sử dụng MariaDB 10.2, MySQL 8 trở lên, bạn có thể làm điều này hiệu quả hơn và tôi nghĩ rõ ràng hơn, bằng cách sử dụng các biểu thức bảng và hàm cửa sổ phổ biến .
WITH ordering AS (
SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.*
FROM example ORDER BY name
)
SELECT * FROM ordering WHERE MOD(n, 5) = 0;
Về mặt khái niệm, điều này tạo ra một bảng tạm thời với nội dung của example
bảng được sắp xếp theo name
trường, thêm một trường bổ sung được gọi n
là số hàng và sau đó chỉ tìm nạp những hàng có số chính xác chia hết cho 5, tức là mọi hàng thứ 5. Trong thực tế, cơ sở dữ liệu thường có thể tối ưu hóa điều này tốt hơn thế. Nhưng ngay cả khi nó không tối ưu hóa nó nữa, tôi nghĩ nó rõ ràng hơn là sử dụng các biến người dùng lặp đi lặp lại như bạn đã làm trong các phiên bản MySQL trước đó.
Nếu bạn không yêu cầu số hàng trong tập kết quả, bạn có thể đơn giản hóa truy vấn.
SELECT
[column name]
FROM
(SELECT @row:=0) temp,
[table name]
WHERE (@row:=@row + 1) % [n] = 1
Thay thế các trình giữ chỗ sau:
[column name]
bằng danh sách các cột bạn cần tìm nạp.[table name]
bằng tên bảng của bạn.[n]
bằng một số. Ví dụ: nếu bạn cần mỗi hàng thứ 5, hãy thay thế nó bằng 5