SQL / Python: объединение нескольких записей из «связанных» таблиц в одну строку, разделенную запятыми, для каждой записи - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть данные в 3 таблицах. Для каждой записи в tblDataDef у меня есть несколько тегов (например, хэштег или категория). Эти теги хранятся в tblDataTags, где для каждого тега есть запись (D_ID - это идентификатор tblDataDef, TAG_ID - это идентификатор tblTags).

Например, предположим, что в моей первой записи есть теги ("a", «б», «c»). Следующее будет означать, что:

tblDataDef| **ID=1**  

tblDataTags| ID=47, **D_ID=1**, *TAG_ID=1*  
tblDataTags| ID=48, **D_ID=1**, *TAG_ID=2*  
tblDataTags| ID=49, **D_ID=1**, *TAG_ID=3*  

tblTags| *ID=1*, TAG="a"  
tblTags| *ID=2*, TAG="b"  
tblTags| *ID=3*, TAG="c"  

Мне нужно создать новый столбец / поле с разделенной запятыми строкой ВСЕХ тегов, связанных с каждым идентификатором из tblDataDef. Таким образом, новое поле будет заполнено "a, b, c" для примера выше. Я делаю это, чтобы заполнить столбец TreeView в tkinter.

Мой текущий метод занимает немного времени, потому что он выполняет тысячи запросов, поскольку он перебирает идентификаторы tblDataDef. Есть ли более быстрый способ? Спасибо !!

Загрузка данных tblDataDef:

def load_data():
    conn = pyodbc.connect(strConn)
    strSQL = "SELECT ID, ITEM, DESCRIP FROM tblDataDef"
    df = pd.read_sql_query(strSQL, conn)
    conn.close()
    return df

Загрузка тегов (для одного идентификатора из tblDataDef):

def load_data_tags(series):
    conn = pyodbc.connect(strConn)   
    strSQL = ("SELECT tblTags.TAG "
              "FROM tblDataTags "
              "LEFT JOIN tblTags ON tblDataTags.TAG_ID=tblTags.ID "
              f"WHERE D_ID = {series}")  
    df = pd.read_sql_query(strSQL, conn)
    conn.close()
    return df

Заполнение TreeView tkinter данными:

df = load_data()
for i, r in df.iterrows():
    _id = self.tree.insert("", index="end")
    self.tree.set(_id, column="ID", value=r["ID"])
    self.tree.set(_id, column="Item", value=r["ITEM"])
    self.tree.set(_id, column="Description", value=r["DESCRIP"])

    tags = load_data_tags(r["ID"])
    tags = tags["TAG"].values.tolist()
    tags = ";".join(tags)
    self.tree.set(_id, column="Tags", value=tags)

1 Ответ

0 голосов
/ 08 апреля 2020

Если используемый движок базы данных поддерживает функцию агрегирования GROUP_CONCAT() (поддерживается MySQL и sqlite3), то вы можете объединить две функции load_data() и load_data_tags() в одну:

def load_all_data():
    strSQL = ('SELECT dd.ID, ITEM, DESCRIP, GROUP_CONCAT(TAG) AS TAGS '
              'FROM tblDataDef dd, tblDataTags dt, tblTags t '
              'WHERE dd.ID = dt.D_ID AND dt.TAG_ID = t.ID '
              'GROUP BY dd.ID')
    df = pd.read_sql_query(strSQL, conn)
    return df

Затем заполните результат:

df = load_all_data()
for i, r in df.iterrows():
    _id = tree.insert('', index='end')
    tree.set(_id, column='ID', value=r['ID'])
    tree.set(_id, column='Item', value=r['ITEM'])
    tree.set(_id, column='Description', value=r['DESCRIP'])
    tree.set(_id, column='Tags', value=r['TAGS'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...