Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Khoảng trống và đảo trên 2 cột - nếu cột A liên tiếp và cột B giống hệt nhau

Không có nhiều thay đổi trong truy vấn của bạn. Về cơ bản, bạn cần chọn namenumber trong truy vấn con và sắp xếp theo cùng một thứ tự. Sau đó, bạn có thể nhóm theo name, number - rn trong truy vấn bên ngoài.

SELECT
    min(number) first_number,
    max(number) last_number,
    count(*) AS no_records,
    name
FROM (
    SELECT c.*, @rn := @rn + 1 rn
    from (
        SELECT name, number
        FROM `table`
        WHERE cc = 1
        ORDER BY name, number
        LIMIT 99999999999999999
    ) AS c
    CROSS JOIN (SELECT @rn := 0) r
) c
GROUP BY name, number - rn 
ORDER BY first_number ASC, name ASC;

Kết quả:

first_number  last_number  no_records  name
           1            2           2  Apple
           3            3           1  Bean
          10           12           3  Hello
          14           14           1  Deer
          14           14           1  Door
          15           15           1  Hello
          17           17           1  Hello

db <> fiddle

Tôi thường ủng hộ việc chống lại việc sử dụng các biến phiên theo cách này. Lý do là các giải pháp như vậy phụ thuộc vào việc triển khai nội bộ và có thể bị phá vỡ bởi các bản cập nhật phiên bản hoặc thay đổi cài đặt. Ví dụ:Khi MariaDB quyết định bỏ qua mệnh đề ORDER BY trong các truy vấn con mà không có LIMIT. Đây là lý do tại sao tôi bao gồm một LIMIT rất lớn.

Tôi cũng đã thay thế number với first_number trong mệnh đề ORDER BY bên ngoài để tránh sự cố với chế độ ONLY_FULL_GROUP_BY.

Một cách ổn định hơn để tạo số hàng là sử dụng cột AOTO_INCREMENT trong bảng tạm thời:

drop temporary table if exists tmp_tbl;

create temporary table tmp_tbl (
  rn int unsigned auto_increment primary key,
  name varchar(64) not null,
  number int not null
);

insert into tmp_tbl (name, number)
  select name, number
  from `table`
  order by name, number;

Truy vấn SELECT cuối cùng giống với truy vấn bên ngoài ở trên:

SELECT
    min(number) first_number,
    max(number) last_number,
    count(*) AS no_records,
    name
FROM tmp_tbl
GROUP BY name, number - rn 
ORDER BY first_number ASC, name ASC;

db <> fiddle

Trong phiên bản mới hơn (bắt đầu từ MariaDB 10.2), bạn có thể sử dụng ROW_NUMBER() chức năng cửa sổ thay thế:

SELECT
    min(number) first_number,
    max(number) last_number,
    count(*) AS no_records,
    name
FROM (
    SELECT
        name,
        number,
        row_number() OVER (ORDER BY name, number) as rn
    FROM `table`
    WHERE cc = 1
) c
GROUP BY name, number - rn 
ORDER BY first_number ASC, name ASC;

db <> fiddle



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL có sử dụng các chỉ mục hiện có để tạo chỉ mục mới không?

  2. Truy xuất chỉ mục của một hàng đã chèn

  3. Mysql chọn các giá trị đếm từ một cột duy nhất

  4. Kết quả PDOStatement ::rowCount khi được sử dụng sau PDO ::commit?

  5. Tìm kiếm toàn văn MySQL cho các từ có ba chữ cái trở xuống