我正在开发一个类似于商店的系统(在PHP和MySQL中),它将发票导出到外部系统。过程就是这样的;
对于发送到外部服务器的每个XML,在数据库中创建一条记录,其中包含相应的invoicenumber和状态(状态最初为SENT
,表示已发送XML。)系统处理完毕后状态为SUCCESS
或ERROR
的回复。现在,问题是;在某些时候,我想获取状态为SUCCESS
的请求表中没有记录的发票列表。
编辑:如果状态为ERROR
,则会有针对同一发票的新请求,因此每张发票可能会有多个请求。
我的订单表包含ID
和InvoiceNumber
列,请求表包含ID
,InvoiceNumber
和Status
列,因此要获取提及的列表我可以做类似的事情:
SELECT InvoiceNumber
FROM orders AS a
LEFT JOIN requests AS b
ON a.InvoiceNumber = b.InvoiceNumber
WHERE NOT EXISTS (SELECT ID
FROM requests
WHERE status = "SUCCESS"
AND request.InvoiceNumber = a.InvoiceNumber)
但是,第二个选项是为订单表创建一个额外的列(即。requestSucces
),最初为0,如果系统处理相应发票的成功响应,则设置为1。这将导致更容易和更便宜的查询以获取需要(重新)发送的发票列表(SELECT invoiceNumber FROM orders WHERE requestSuccess = 0
),但是该字段在技术上将是多余的。
我的问题是:什么会更好;以冗余字段为代价使用简单查询或使用较重的查询而不用冗余污染数据库。当然;如果你们中任何人都知道一个更好的解决方案,而不使用更好的冗余。
答案 0 :(得分:2)
当您将状态字段设置为数字错误= 0且成功= 1时,您可以执行按发票编号分组的最大状态,以查看哪些发票不是
答案 1 :(得分:0)
战争胜过正常化: - )
但:
由于您正在寻找未设置为success
的发票,您不能这样做吗?
SELECT InvoiceNumber
FROM requests
WHERE status != "SUCCESS"
(注意不等号)
答案 2 :(得分:0)
根据您提供的信息,似乎每个发票的“请求”表中始终至少有一个条目,您可以从这样的查询中获取所需的数据:
SELECT InvoiceNumber
FROM Requests AS r_error
LEFT JOIN Requests AS r_success
ON (r_error.InvoiceNumber=r_success.InvoiceNumber AND r_error.status!='SUCCESS'
AND r_success.status='SUCCESS')
WHERE r_success.InvoiceNumber IS NULL
我不确定它会闪电般快但我认为它比你的初始查询更快(我没有测试过这个理论!)但更重要的是它没有使用你的订单表所以不应该影响您的交易处理尽可能多。