我有两个表,SALES_REP和UNAVAILABLE DATES:
import sqlite3
booking = sqlite3.connect('AppointmentBookingSystem.db')
booking.execute('''CREATE TABLE SALES_REP
(repID INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL COLLATE NOCASE,
numberOfAppointments INT DEFAULT 0,
FOREIGN KEY (username) REFERENCES USERNAME_PASSWORD(username));''')
booking.execute('''CREATE TABLE UNAVAILABLE_DATES
(dateID INTEGER PRIMARY KEY AUTOINCREMENT,
date DATE NOT NULL);''')
这两个表之间的关系是多对多的,所以我创建了一个带有复合主键的链接表:
booking.execute('''CREATE TABLE DATES_REPS
(dateID INTEGER NOT NULL,
repID INTEGER NOT NULL,
PRIMARY KEY(dateID, repID),
FOREIGN KEY (dateID) REFERENCES UNAVAILABLE_DATES(dateID),
FOREIGN KEY (repID) REFERENCES SALES_REP(repID));''')
我正在尝试使用SQL select语句来获取SALES_REP中所有在UNAVAILABLE_DATES表中日期不存在的repID的列表
date = 2015-09-25
c = booking.cursor()
cursor = c.execute('SELECT SALES_REP.repID FROM SALES_REP, DATES_REPS, UNAVAILABLE_DATES\
WHERE UNAVAILABLE_DATES.date=? AND UNAVAILABLE_DATES.dateID = DATES_REPS.dateID AND SALES_REP.repID != DATES_REPS.repID', (date,))
IDs = c.fetchall()
当我在DATES_REPS表中只有1条记录时,这是按预期工作的
SALES_REP TABLE
repID
------
1
2
3
UNAVAILABLE_DATES TABLE
dateID | date
---------------
1 2015-09-25
DATES_REPS
dateID | repID
-------------------
1 1
返回:
IDs = [(2,), (3,)]
然而,在将另一条记录添加到DATES_REPS和UNAVAILABLE_DATES表之后,select语句不再正常工作
SALES_REP TABLE
repID
------
1
2
3
UNAVAILABLE_DATES TABLE
dateID | date
---------------
1 2015-09-25
2 2015-09-25
DATES_REPS
dateID | repID
-------------------
1 1
2 2
我现在希望得到的回报是' 3'但我得到
IDs = [(1,), (2,), (3,), (3,)]
当我向UNAVAILABLE_DATES和DATES_REPS添加更多记录时,此模式仍在继续
我假设正在发生的是为DATES_REPS表中的每条记录返回SALES_REP.repID!= DATES_REPS.repID(所以当存在1时,返回2和3,当2存在时1和3返回等)而不是这个日期整个表中没有的repID
这与我的表格连接方式有关吗?或者我的select语句中存在问题?
答案 0 :(得分:0)
您已正确推断出SQL如何评估查询。
如果要检查某些行是否不存在,则应使用NOT EXISTS(使用correlated subquery):
SELECT repID
FROM SALES_REP
WHERE NOT EXISTS (SELECT 1
FROM DATES_REPS
JOIN UNAVAILABLE_DATES USING (dateID)
WHERE UNAVAILABLE_DATES.date = ?
AND SALES_REP.repID = DATES_REPS.repID)
答案 1 :(得分:0)
仅为date
创建多对多关系是不寻常的。只需两张表,您的设计就会更简单:
SalesPerson: ID, Name, ...
SalesPersonUnavailable: SalesPersonID, Date
在(SalesPersonID, Date)
上使用主键以保持一致性。
现在您可以查询:
select name
from SalesPerson sp
where not exists
(
select *
from SalesPersonUnavailable spu
where spu.Date = ?
and sp.ID = spu.SalesPersonID
)