我无法让我的基本SQL查询工作,因为它返回0值,尽管有明显的空值
SELECT
*
FROM
leads AS l
JOIN closes c ON l.id = c.lead_id
WHERE
c.close_date IS NULL
CREATE TABLE closes
(
id INT AUTO_INCREMENT
PRIMARY KEY,
lead_id INT NOT NULL,
close_date DATETIME NULL,
close_type VARCHAR(255) NULL,
primary_agent VARCHAR(255) NULL,
price FLOAT NULL,
gross_commission FLOAT NULL,
company_dollar FLOAT NULL,
address VARCHAR(255) NULL,
city VARCHAR(255) NULL,
state VARCHAR(10) NULL,
zip VARCHAR(10) NULL,
CONSTRAINT closes_ibfk_1
FOREIGN KEY (lead_id) REFERENCES leads (id)
)
ENGINE = InnoDB;
CREATE INDEX lead_id
ON closes (lead_id);
我应该提一下,我使用python web scraper和SQLAlchemy插入数据。如果数据未被删除,则插入时将为None
。
这是datagrip的屏幕截图,显示行
中的空值好吧所以我继续在表格中的某些条目上运行以下内容,其值已经是<null>
UPDATE closes
SET close_date = NULL
WHERE
lead_id = <INTEGERVAL>
;
现在有趣的是,在运行原始查询时,我确实返回了我运行更新查询的2条记录(预期结果)。这将使我相信问题在于我的SQLAlchemy模型如何映射插入值。
class Close(db.Model, ItemMixin):
__tablename__ = 'closes'
id = db.Column(db.Integer, primary_key=True)
lead_id = db.Column(db.Integer, db.ForeignKey('leads.id'), nullable=False)
close_date = db.Column(db.DateTime)
close_type = db.Column(db.String(255))
primary_agent = db.Column(db.String(255))
price = db.Column(db.Float)
gross_commission = db.Column(db.Float)
company_dollar = db.Column(db.Float)
address = db.Column(db.String(255))
city = db.Column(db.String(255))
state = db.Column(db.String(10))
zip = db.Column(db.String(10))
def __init__(self, item):
self.build_from_item(item)
def build_from_item(self, item):
for k, v in item.items():
setattr(self, k, v)
但我相信,如果没有从网站上删除任何值,则值为py None
。我的理解是SQLAlchemy会在插入时将None
映射到NULL
,并且假设nullable=True
是默认设置,可以在生成的DDL上看到,我仍然感到茫然为什么它似乎是NULL
,而实际上它并不是那样的行为。
只有在我认为问题发生的地方,我的蜘蛛实际上会抓取数据并将其分配给Item
,如下所示
# item['close_date'] = None at this point
try:
item['close_date'] = arrow.get(item['close_date'], 'MMM D, YYYY').format('YYYY-MM-DD')
except ParserError as e:
# Maybe item['close_date'] = None here?
spider.logger.error(f'Parse error: {item["close_date"]} - {e}')
在我写的python代码中,这似乎是问题出现的地方。但如果arrow.get
引发异常,item['close_date']
的值仍应为None
。如果不是这种情况,即使它不能解释为什么看起来记录值为NULL
,甚至认为它的行为不像它。
答案 0 :(得分:1)
我猜你是否遇到了连接问题,而不是NULL值。以下查询为我返回1个结果。有关您的数据,用于查询的软件(我使用SQL Yog测试过)以及适用版本的更多信息可能有所帮助。
修改强>
可能是您遇到了MySQL的“零日期”问题。 https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
MySQL允许您存储&#39; 0000-00-00&#39;作为一个“假人 date。“在某些情况下,这比使用NULL值更方便 并使用较少的数据和索引空间。要禁用&#39; 0000-00-00&#39;,请启用 NO_ZERO_DATE模式。
我已更新下面的SQL数据,以在INSERT和SELECT的WHERE中包含零日期。
DROP TABLE IF EXISTS closes;
DROP TABLE IF EXISTS leads;
CREATE TABLE leads (
id INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
INSERT INTO leads(id) VALUES (1),(2),(3);
CREATE TABLE closes (
id INT(11) NOT NULL AUTO_INCREMENT,
lead_id INT(11) NOT NULL,
close_date DATETIME DEFAULT NULL,
close_type VARCHAR(255) DEFAULT NULL,
primary_agent VARCHAR(255) DEFAULT NULL,
price FLOAT DEFAULT NULL,
gross_commission FLOAT DEFAULT NULL,
company_dollar FLOAT DEFAULT NULL,
address VARCHAR(255) DEFAULT NULL,
city VARCHAR(255) DEFAULT NULL,
state VARCHAR(10) DEFAULT NULL,
zip VARCHAR(10) DEFAULT NULL,
PRIMARY KEY (id),
KEY lead_id (lead_id),
CONSTRAINT closes_ibfk_1 FOREIGN KEY (lead_id) REFERENCES leads (id)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
INSERT INTO closes(id,lead_id,close_date,close_type,primary_agent,price,gross_commission,company_dollar,address,city,state,zip)
VALUES
(1,3,'0000-00-0000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(2,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(3,2,'2018-01-09 17:01:44',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
SELECT
*
FROM
leads AS l
JOIN closes c ON l.id = c.lead_id
WHERE
c.close_date IS NULL OR c.close_date = '0000-00-00';