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

Làm thế nào để đếm tất cả các giá trị NULL trong một bảng?

Nếu bạn muốn điều này được thực hiện độc quyền bởi MYSQL và không liệt kê tất cả các cột, hãy xem giải pháp này.

Trong phương pháp này, bạn không phải duy trì số lượng cột cơ sở dữ liệu bằng cách mã hóa chúng. Nếu lược đồ bảng của bạn được sửa đổi, phương pháp này sẽ hoạt động và không yêu cầu thay đổi mã.

SET @db = 'testing'; -- database
SET @tb = 'fuzzysearch'; -- table
SET @x = ''; -- will hold the column names with ASCII method applied to retrieve the number of the first char
SET @numcolumns = 0; -- will hold the number of columns in the table

-- figure out how many columns we have
SELECT count(*) into @numcolumns FROM information_schema.columns where [email protected] and [email protected];

-- we have to prepare some query from all columns of the table
SELECT group_concat(CONCAT('ASCII(',column_name,')') SEPARATOR ",") into @x from information_schema.columns where [email protected] and [email protected];
-- after this query we have a variable separated with comma like
-- ASCII(col1),ASCII(col2),ASCII(col3)

-- we now generate a query to concat the columns using comma as separator (null values are omitted from concat)
-- then figgure out how many times the comma is in that substring (this is done by using length(value)-length(replace(value,',',''))
-- the number returned is how many non null columns we have in that column
-- then we deduct the number from the known number of columns, calculated previously
-- the +1 is added because there is no comma for single value
SET @s = CONCAT('SELECT @numcolumns - (length(CONCAT_WS(\',\',', @x, '))-length(replace(CONCAT_WS(\',\',', @x, '),\',\',\'\')) + 1) FROM ',@db,'.',@tb,';');
PREPARE stmt FROM @s;
EXECUTE stmt;
-- after this execution we have returned for each row the number of null columns
-- I will leave to you to add a sum() group call if you want to find the null values for the whole table
DEALLOCATE PREPARE stmt;

ASCII được sử dụng để tránh việc đọc, nối các cột rất dài mà không làm gì cả, ASCII cũng giúp chúng ta an toàn cho các giá trị trong đó ký tự đầu tiên là dấu phẩy (,).

Vì bạn đang làm việc với các báo cáo, bạn có thể thấy điều này hữu ích vì nó có thể được sử dụng lại cho mỗi bảng nếu bạn đưa vào một phương pháp.

Tôi đã cố gắng để càng nhiều bình luận càng tốt.

Hãy chia thành từng phần theo cách nhỏ gọn ở trên (cách ngược lại):

Tôi muốn kết thúc một truy vấn như thế này

SELECT totalcolumns - notnullcolumns from table; -- to return null columns for each row

Mặc dù cái đầu tiên rất dễ bị cắt bằng cách chạy:

SELECT count(*) FROM information_schema.columns where [email protected] and [email protected];

Điều thứ hai là notnullcolumns là một chút khó khăn.

Vì vậy, chạy một truy vấn như thế này:

SELECT CONCAT_WS(",","First name",NULL,"Last Name");
returns: 'First name,Last Name'

Điều này là tốt, chúng tôi loại bỏ các giá trị null khỏi liệt kê. Nhưng làm thế nào để chúng tôi có được bao nhiêu cột thực sự được nối?

Vâng, đó là khó khăn. Chúng ta phải tính số dấu phẩy + 1 để có được các cột thực sự được nối.

Đối với thủ thuật này, chúng tôi đã sử dụng ký hiệu SQL sau

select length(value)-length(replace(value,',','')) +1 from table

Ok, vậy chúng ta đã có số cột được nối.

Nhưng phần khó hơn sẽ đến tiếp theo.

Chúng ta phải liệt kê CONCAT_WS () tất cả các giá trị.
Chúng ta cần có một cái gì đó như sau:

SELECT CONCAT_WS(",",col1,col2,col3,col4,col5);

Đây là nơi chúng ta phải sử dụng các câu lệnh đã chuẩn bị sẵn, vì chúng ta phải chuẩn bị động một truy vấn SQL từ các cột chưa biết. Chúng tôi không biết có bao nhiêu cột trong bảng của mình.

Vì vậy, đối với điều này, chúng tôi sử dụng dữ liệu từ bảng cột information_schema. Chúng ta cần chuyển tên bảng, cũng như tên cơ sở dữ liệu, vì chúng ta có thể có cùng tên bảng trong các cơ sở dữ liệu riêng biệt.

Chúng tôi cần một truy vấn trả về col1, col2, col3, col4, col5 cho chúng tôi trên CONCAT_WS "string"

Vì vậy, đối với điều này, chúng tôi chạy một truy vấn

SELECT group_concat(column_name SEPARATOR ",") into @x from information_schema.columns where [email protected] and [email protected];

Một điều nữa cần đề cập. Khi chúng ta sử dụng phương thức length () và Replace () để tìm xem có bao nhiêu cột được nối với nhau, chúng ta phải đảm bảo rằng chúng ta không có dấu phẩy giữa các giá trị. Nhưng cũng lưu ý rằng chúng ta có thể có các giá trị thực sự dài trong các ô cơ sở dữ liệu của mình. Đối với cả hai thủ thuật này, chúng tôi sử dụng phương thức ASCII ('value'), phương thức này sẽ trả về ASCII char của char đầu tiên, không thể là dấu phẩy và sẽ trả về null cho các cột rỗng.

Điều đó đang được nói rằng chúng tôi có thể thu gọn tất cả những điều này trong giải pháp toàn diện ở trên.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tối ưu hóa việc gọi dữ liệu trong JDBC vào JTable

  2. Cơ sở dữ liệu kết quả là đối tượng hay mảng?

  3. Hoàn thành Hướng dẫn xóa mềm &khôi phục bản ghi đã xóa của Laravel 8

  4. Thay thế cho Intersect trong MySQL

  5. Làm thế nào mà SQL này có thể sai? Tôi không nhìn thấy gì?