Python / Sqlite3: LEFT JOIN with GROUP_CONCAT
Python / Sqlite3: LEFT JOIN with GROUP_CONCAT
我有 2 个表:
Tasks: Predecessors:
ID | Task | Team ID | TaskID | PredecessorID
---+------+------ ---+--------+--------------
1 | A | 1 1 | 1 | None
2 | B | 1 2 | 2 | 1
3 | C | 2 3 | 3 | 1
4 | D | 2 4 | 3 | 2
5 | 4 | None
我想 select 团队 2 的所有任务,并为每个任务添加 前任任务,用逗号分隔 形式:
ID | Task | Team | Predecessors
---+------+------+-------------
3 | C | 2 | 1, 2
4 | D | 2 | None
因此我使用以下 SQL-查询:
SELECT Tasks.*, GROUP_CONCAT(Predecessors.PredecessorID)
FROM Tasks LEFT JOIN Predecessors ON Tasks.ID = Predecessors.TaskID
WHERE Tasks.Team = 2 GROUP BY Predecessors.TaskID
哪个returns:
ID | Task | Team | Predecessors
---+------+------+-------------
3 | C | 2 | 1, 2
我该怎么做才能获得具有 None 值的行?
这是我的测试代码:
# -*- coding: utf-8 -*-
import sqlite3
con = sqlite3.connect('test.db')
cur = con.cursor()
# Drop old tables if they already exits and create new ones. (For testing).
cur.execute("""DROP TABLE IF EXISTS Tasks""")
cur.execute("""DROP TABLE IF EXISTS Predecessors""")
# Create tables.
cur.execute("""CREATE TABLE Tasks (ID INTEGER PRIMARY KEY AUTOINCREMENT,
Task TEXT, Team INTEGER)""")
cur.execute("""CREATE TABLE Predecessors (ID INTEGER PRIMARY KEY AUTOINCREMENT,
TaskID INTEGER, PredecessorID INTEGER)""")
# Insert some values.
sql = """INSERT INTO Tasks (Task, Team) VALUES (?, ?)"""
for task in [('A', 1), ('B', 1), ('C', 2), ('D', 3)]:
cur.execute(sql, task)
sql = """INSERT INTO Predecessors (TaskID, PredecessorID) VALUES (?, ?)"""
for predecessor in [(1, None), (2, 1), (3, 1), (3, 2), (4, None)]:
cur.execute(sql, predecessor)
con.commit()
sql = """SELECT Tasks.*, GROUP_CONCAT(Predecessors.PredecessorID)
FROM Tasks LEFT JOIN Predecessors ON Tasks.ID = Predecessors.TaskID
WHERE Tasks.Team = 2 GROUP BY Predecessors.TaskID"""
cur.execute(sql)
data = cur.fetchall()
print data
con.close()
感谢帮助!!
问题是GROUP BY Predecessors.TaskID
;对于没有匹配项的行,所有 Predecessors
列都是 NULL。
只需使用 GROUP BY Tasks.ID
即可。
你应该检查你的代码 carefully.nothing 在你的 sql 中是错误的,你只是写错了测试数据。
your test data[('A', 1), ('B', 1), ('C', 2), ('D', 3)]
and it should be [('A', 1), ('B', 1), ('C', 2), ('D', 2)]
我有 2 个表:
Tasks: Predecessors:
ID | Task | Team ID | TaskID | PredecessorID
---+------+------ ---+--------+--------------
1 | A | 1 1 | 1 | None
2 | B | 1 2 | 2 | 1
3 | C | 2 3 | 3 | 1
4 | D | 2 4 | 3 | 2
5 | 4 | None
我想 select 团队 2 的所有任务,并为每个任务添加 前任任务,用逗号分隔 形式:
ID | Task | Team | Predecessors
---+------+------+-------------
3 | C | 2 | 1, 2
4 | D | 2 | None
因此我使用以下 SQL-查询:
SELECT Tasks.*, GROUP_CONCAT(Predecessors.PredecessorID)
FROM Tasks LEFT JOIN Predecessors ON Tasks.ID = Predecessors.TaskID
WHERE Tasks.Team = 2 GROUP BY Predecessors.TaskID
哪个returns:
ID | Task | Team | Predecessors
---+------+------+-------------
3 | C | 2 | 1, 2
我该怎么做才能获得具有 None 值的行?
这是我的测试代码:
# -*- coding: utf-8 -*-
import sqlite3
con = sqlite3.connect('test.db')
cur = con.cursor()
# Drop old tables if they already exits and create new ones. (For testing).
cur.execute("""DROP TABLE IF EXISTS Tasks""")
cur.execute("""DROP TABLE IF EXISTS Predecessors""")
# Create tables.
cur.execute("""CREATE TABLE Tasks (ID INTEGER PRIMARY KEY AUTOINCREMENT,
Task TEXT, Team INTEGER)""")
cur.execute("""CREATE TABLE Predecessors (ID INTEGER PRIMARY KEY AUTOINCREMENT,
TaskID INTEGER, PredecessorID INTEGER)""")
# Insert some values.
sql = """INSERT INTO Tasks (Task, Team) VALUES (?, ?)"""
for task in [('A', 1), ('B', 1), ('C', 2), ('D', 3)]:
cur.execute(sql, task)
sql = """INSERT INTO Predecessors (TaskID, PredecessorID) VALUES (?, ?)"""
for predecessor in [(1, None), (2, 1), (3, 1), (3, 2), (4, None)]:
cur.execute(sql, predecessor)
con.commit()
sql = """SELECT Tasks.*, GROUP_CONCAT(Predecessors.PredecessorID)
FROM Tasks LEFT JOIN Predecessors ON Tasks.ID = Predecessors.TaskID
WHERE Tasks.Team = 2 GROUP BY Predecessors.TaskID"""
cur.execute(sql)
data = cur.fetchall()
print data
con.close()
感谢帮助!!
问题是GROUP BY Predecessors.TaskID
;对于没有匹配项的行,所有 Predecessors
列都是 NULL。
只需使用 GROUP BY Tasks.ID
即可。
你应该检查你的代码 carefully.nothing 在你的 sql 中是错误的,你只是写错了测试数据。
your test data[('A', 1), ('B', 1), ('C', 2), ('D', 3)]
and it should be [('A', 1), ('B', 1), ('C', 2), ('D', 2)]