【问题标题】:SQLite3 - cross table SELECT queriesSQLite3 - 跨表 SELECT 查询
【发布时间】:2021-07-13 01:20:20
【问题描述】:

我想要返回的是性能表中的所有booking_id 与预订表中night = 1 的所有booking_ids 匹配的所有seat_ids - 是INNER JOIN 的最佳方式做吗?

还是更像"""SELECT seat_id FROM performance WHERE booking_id=(SELECT * FROM booking WHERE night = ?""", (night_number))

上面我得到sqlite3.OperationalError: incomplete input错误。

connection = sqlite3.connect('collyers_booking_system.db')
cursor = connection.cursor()

cursor.execute(booking_table)
cursor.execute(performance_table)

connection.commit()

booking_table = """CREATE TABLE IF NOT EXISTS
booking(
booking_id TEXT PRIMARY KEY,
customer_id INTEGER,
night INTEGER,
cost REAL,
FOREIGN KEY (customer_id) REFERENCES customer(customer_id)
)"""

performance_table = """CREATE TABLE IF NOT EXISTS
performance(
performance_id TEXT PRIMARY KEY,
seat_id TEXT,
booking_id INTEGER,
FOREIGN KEY (seat_id) REFERENCES seat(seat_id),
FOREIGN KEY (booking_id) REFERENCES booking(booking_id),
)"""

night_number = 1

cursor.execute("""SELECT seat_id FROM performance INNER JOIN booking ON night=?""", (night_number))
booked_seats = cursor.fetchall()

print(booked_seats)

这样我得到ValueError: parameters are of unsupported type 错误。

【问题讨论】:

    标签: python sql sqlite select


    【解决方案1】:

    首先,如果这是您的实际代码,则表 performanceCREATE 语句中有错字。
    您必须删除末尾的,

    FOREIGN KEY (booking_id) REFERENCES booking(booking_id), 
    

    那么,这里:

    cursor.execute("""SELECT seat_id FROM performance WHERE booking_id=(SELECT * FROM booking WHERE night = ?""", (night_number))
    

    您错过了 sql 语句的右括号,子查询可能返回多于 1 行,因此您应该使用 = 而不是 IN
    此外,参数night_number 应作为元组传递,而不仅仅是数字,通过在括号内添加,

    cursor.execute("""SELECT seat_id FROM performance WHERE booking_id IN (SELECT * FROM booking WHERE night = ?)""", (night_number,))
    

    对于连接,您需要一个适当的 ON 子句,它链接表和 , 以创建 night_number 的元组:

    sql = """
    SELECT p.seat_id 
    FROM performance p INNER JOIN booking b 
    ON b.booking_id = p. booking_id
    WHERE b.night=?
    """
    cursor.execute(sql, (night_number,))
    

    两种方式,运算符IN 和连接都可以工作。
    还有另一种有时表现更好的选择,这是EXISTS

    sql = """
    SELECT p.seat_id 
    FROM performance p 
    WHERE EXISTS (
      SELECT 1 FROM booking b 
      WHERE b.night=? AND b.booking_id = p.booking_id
    )
    """
    cursor.execute(sql, (night_number,))
    

    【讨论】:

    • 好的,谢谢 - 我有点困惑 sql 变量的用途以及 bp 的来源。这是否需要在 SELECT 语句之上?
    • @BenjaminMcDowell sql 变量存储 sql 语句,它是 execute() 的第一个参数。 p 和 b 是表的别名,它们用于限定列名,以便没有歧义。例如:b.booking_id = p.booking_id 明确指出哪一列是哪一列,因为 b 指的是预订,p 指的是性能。
    【解决方案2】:

    您正在将列表结果与整数进行比较。

    this SELECT * FROM booking WHERE night = ? => 返回 N 行 而你正在等待一个整数SELECT seat_id FROM performance WHERE booking_id=?

    你必须使用这样的东西:

    SELECT seat_id FROM performance WHERE booking_id in (SELECT * FROM booking WHERE night = ?""", (night_number))
    

    【讨论】:

    • 错误仍然存​​在,因为您没有传入元组。
    猜你喜欢
    • 1970-01-01
    • 2017-04-25
    • 2011-12-10
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多