Для цикла по определенным столбцам таблицы и перехода к оператору реляционного SQL

Я хочу перебирать столбцы ['A', 'B', 'C'] и передавать имена столбцов оператору выбора в SQL, например

SELECT * FROM table_name
WHERE table_name.`A` IS NULL

Таким образом, каждый оператор выбора будет возвращать набор результатов на основе имени столбца. Это будет содержаться в сценарии sql. Затем я читал каждый результат через соединение с базой данных Python, например mysql-коннектор. Как бы я это сделал? Спасибо!

Изменить. Я хочу сохранить решение строго в рамках SQL.

🤔 А знаете ли вы, что...
Существует множество различных реляционных баз данных, таких как MySQL, PostgreSQL, Oracle и Microsoft SQL Server, которые используют SQL, но могут иметь свои особенности.


65
3

Ответы:

Создайте запрос динамически в Python в цикле.

cols = ['A', 'B', 'C']

for col in cols:
    sql = f'SELECT * FROM table_name WHERE `{col}` IS NULL'
    cursor.execute(sql)
    # process the results of the query

Взят пример sqlite. Но запросы будут аналогичны для других последовательных баз данных, таких как mysql или mssql. Ниже будут выполняться запросы для каждого столбца, имеющего значение NULL. И для каждого запроса он создаст 2D-список и сохранит его как значение dict. Ключевые имена dict будут соответствующими именами столбцов. Вы можете обработать данные из dict

import sqlite3

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

dct = {}

columns = ['A', 'B', 'C']

for column in columns:

    qry = f'SELECT * FROM table_name WHERE {column} IS NULL'

    cursor.execute(qry)

    # fetch the results
    r = cursor.fetchall()
    
    # create a 2d list of each colum
    dct[column] = [list(row) for row in r]

conn.close()

Для MySQL вы можете использовать модуль mysql.connector, а для MSSQL — модуль pyodbc для подключения.


Решено

Возможно, вы могли бы прочитать все свои данные из базы данных и сгенерировать команды sql. Если я правильно понял, вам нужны сформированные команды sql для получения данных, в которых отдельные столбцы имеют значение NULL.
Давайте создадим две таблицы для работы:

--    S a m p l e    D a t a :
Create Table tbl_1 ( id Int, a Varchar(12), b Varchar(12), c Decimal );
Insert Into tbl_1 VALUES ( 1, 'ABCD', 'EFGH', 3.5 ), 
                         ( 2, 'OPQR',  Null,  1.2 ), 
                         ( 3, Null,   'STUV', 7.1 ),
                         ( 4, 'KLMN', 'WXYZ', Null);

Create Table tbl_2 ( id Int, x Varchar(12), y Varchar(12), z Varchar(12) );
Insert Into tbl_2 VALUES ( 1, 'XX',  'YY', '*' ), 
                         ( 2, 'AA', Null,  '**' ), 
                         ( 3, Null,  'BB', '***'),
                         ( 4, 'CC',  'DD', Null);

... имена столбцов в ваших таблицах можно получить из INFORMATION_SCHEMA.COLUMNS.

WITH
  tbl_cols AS
    ( SELECT   TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION
      FROM     INFORMATION_SCHEMA.COLUMNS
      WHERE    TABLE_SCHEMA = 'your_schema_name' 
               /* And TABLE_NAME = tbl_1 (if you want just that table) */
      ORDER BY TABLE_NAME, ORDINAL_POSITION 
    ), 

... создайте cte для генерации команды sql SELECT для каждого столбца (столбец id исключен в этом ответе)

  cmds AS
    ( Select Row_Number() Over(Order By TABLE_NAME, ORDINAL_POSITION) as id, 
             TABLE_NAME, COLUMN_NAME, 
             Concat( 'Select ', TABLE_NAME, '.*',  
                     ' From ', TABLE_NAME,
                     ' Where ', TABLE_NAME, '.', COLUMN_NAME, ' Is Null'
                   ) as SQL_CMD
      From   tbl_cols
      Where  COLUMN_NAME != 'id'  /* filtering columns here */
    ) 

... получить данные сверху cte

Select * 
From   cmds;
/*    R e s u l t : 
id  TABLE_NAME  COLUMN_NAME  SQL_CMD
--  ----------  -----------  --------------------------------------------------
1   tbl_1       a            Select tbl_1.* From tbl_1 Where tbl_1.a Is Null
2   tbl_1       b            Select tbl_1.* From tbl_1 Where tbl_1.b Is Null
3   tbl_1       c            Select tbl_1.* From tbl_1 Where tbl_1.c Is Null
4   tbl_2       x            Select tbl_2.* From tbl_2 Where tbl_2.x Is Null
5   tbl_2       y            Select tbl_2.* From tbl_2 Where tbl_2.y Is Null
6   tbl_2       z            Select tbl_2.* From tbl_2 Where tbl_2.z Is Null        */

... выше приведен набор команд sql, определенных для каждой таблицы, имеющей код sql для конкретного столбца...

Более того, если вы создадите еще один cte, который будет собирать вышеуказанные команды sql и объединять их для одной и той же таблицы, вы сможете получить все данные таблицы, которые будут получать определенные команды sql...

  cmds_union AS
    ( SELECT   TABLE_NAME, 
               for_columns, 
               REPLACE(SubStr(SQL_CMD, 1, Length(SQL_CMD) - 11), ',', '') as SQL_CMD
      FROM   
      ( Select   TABLE_NAME, 
                 GROUP_CONCAT(COLUMN_NAME) as for_columns,
                 GROUP_CONCAT(SQL_CMD, ' UNION ALL
' )  as SQL_CMD
        From     cmds 
        Group By TABLE_NAME
      ) a
    )
Select * 
From   cmds_union;
/*      R e s u l t : 
TABLE_NAME  for_columns  SQL_CMD
----------  -----------  -------------------------------------------------------
tbl_1       a,b,c        Select tbl_1.* From tbl_1 Where tbl_1.a Is Null UNION ALL
                         Select tbl_1.* From tbl_1 Where tbl_1.b Is Null UNION ALL
                         Select tbl_1.* From tbl_1 Where tbl_1.c Is Null
                         
tbl_2       x,y,z        Select tbl_2.* From tbl_2 Where tbl_2.x Is Null UNION ALL
                         Select tbl_2.* From tbl_2 Where tbl_2.y Is Null UNION ALL
                         Select tbl_2.* From tbl_2 Where tbl_2.z Is Null              */

См. скрипку здесь.

ПРИМЕЧАНИЕ:
Вы можете фильтровать интересующие таблицы/столбцы и/или корректировать код в соответствии с вашими потребностями. Это просто возможный вариант сделать это строго с помощью sql.