使用时,SELECT语句没有返回正确的值!=(sqlite3)

时间:2015-04-08 13:41:24

标签: python sql python-3.x sqlite

我有两个表,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语句中存在问题?

2 个答案:

答案 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
        )