如何修复生成过多行的查询?
How to fix a query that produces too many rows?
我正在为服务销售设计 Firebird 3.0 数据库,例如美容院等
数据库有 tables:
Serv - 服务列表;
ServRecs - 用于服务销售记录;
Docs - 用于服务文档;
Calc - 用于服务计算,即在特定服务中使用了哪些原始 material,原始数量 material 等;
RecsOut - 对于原始 material 输出记录(销售);
RecsIn - 对于原始 material 输入记录;
库存 - 用于原始 material 和商品的名称和属性。
Serv: Id, name, qnt, Vat...
ServRecs: Id, serv_id, Doc_id, qnt...
文档: doc_id, docN, DocDT, Summ, ...
计算: Id, serv_id, RawMat_id, qnt, unit_id...
RecsOut: id, doc_id, good_id, RecsIn_id
RecsIn: id, good_id...
库存: id, name (Rawaterial's and good's name)...
让我用一个例子来解释:
有服务单据323,里面用到2个服务:serv_id=7(理发)服务和serv_id=8(洗头)服务。由于 ServRecs table 的 qnt 字段显示 serv_id=8 的服务使用了 2 次(即 2 次洗涤,着色前后),serv_id=7 的服务仅使用了 1 次。正如 Calc table 所示,通常,在服务 #7 上使用 raw material with id=11446 15ml 和 id=11448 15ml,在服务 #8 - raw material with id=11450 10毫升。即,总使用量:原始 material 11446 - 15ml、11448 - 15ml 和 11450 - 20ml (2*10ml)。
我的查询如下所示:
select
i.id,
i.name as UsedRawMaterialName,
s.name as ServiceName,
ro.doc_id as ServiceDoc_id,
ri.cost as CostofRawMaterial,
sr.qnt as ServiceQnt, --used service quantity, for example, 2 times washing
sr.qnt*c.qnt as UsedRawMaterialQnt, --used service quantity*rawmaterial's used for 1 service
i.unit_k
from Inventory I, RecsOut ro, RecsIn ri, calc c, servrecs sr, serv s, Docs d, unit u,
where
d.doc_id= ro.doc_id and d.doc_id=sr.doc_id and d.doc_id=323 and
s.id=c.serv_id and sr.serv_id=c.serv_id and
c.rawmat_id=i.id and
ro.recsIn_id=ri.id and
i.unit_k=u.unit_k
我的目标是得到这样的结果:
但是,查询 returns 结果包含冗余记录和错误值,如下所示:
我的查询有什么问题?
更新 1:
我将“旧式 Join 语法”更改为“新式 Join 语法”,很容易发现错误出在“Join RecsOut ro on ro.id=i.id”子句中。 “New-style Join”确实比老式的更加直观。
select
i.id,
i.name as UsedRawMaterialName,
s.name as ServiceName,
ro.doc_id as ServiceDoc_id,
ri.cost as CostofRawMaterial,
sr.qnt as ServiceQnt, --used service quantity, for example, 2 times washing
sr.qnt*c.qnt as UsedRawMaterialQnt, --used service quantity*rawmaterial's used for 1 service
i.unit_k
from
Inventory I Join RecsOut ro on ro.id=i.id
Join RecsIn ri on ro.recsin_id=ri.id
Join calc c on c.rawmat_id=i.id
join ServRecs sr on sr.serv_id=c.serv_id
Join serv s on s.id=c.serv_id
Join doc d on d.doc_id=ro.doc_id and
d.doc_id=sr.doc_id and
d.doc_id=323
join unit u on i.unit_k=u.unit_k
@basti “New Style Join”的一个主要好处是每个 table 都可以在开发和测试期间一次引入一个。对于每个 table“加入”,很容易看出哪个关系产生了比您预期更多(或实际上更少)的记录
翻译您的代码后我发现某处可能有破损。感谢您回复评论 ...
from Inventory I
join RecsOut ro on ro.recsIn_id=ri.id
-- ??? join RecsIn ri, --- ??
join calc c on c.rawmat_id=i.id
join servrecs sr on sr.serv_id=c.serv_id
join serv s on s.id=c.serv_id
join Docs d on d.doc_id= ro.doc_id
and d.doc_id=sr.doc_id
and d.doc_id=323
join unit u on i.unit_k=u.unit_k
不要忘记拥抱内连接、左连接和外连接
我正在为服务销售设计 Firebird 3.0 数据库,例如美容院等
数据库有 tables:
Serv - 服务列表;
ServRecs - 用于服务销售记录;
Docs - 用于服务文档;
Calc - 用于服务计算,即在特定服务中使用了哪些原始 material,原始数量 material 等;
RecsOut - 对于原始 material 输出记录(销售);
RecsIn - 对于原始 material 输入记录;
库存 - 用于原始 material 和商品的名称和属性。
Serv: Id, name, qnt, Vat...
ServRecs: Id, serv_id, Doc_id, qnt...
文档: doc_id, docN, DocDT, Summ, ...
计算: Id, serv_id, RawMat_id, qnt, unit_id...
RecsOut: id, doc_id, good_id, RecsIn_id
RecsIn: id, good_id...
库存: id, name (Rawaterial's and good's name)...
让我用一个例子来解释:
有服务单据323,里面用到2个服务:serv_id=7(理发)服务和serv_id=8(洗头)服务。由于 ServRecs table 的 qnt 字段显示 serv_id=8 的服务使用了 2 次(即 2 次洗涤,着色前后),serv_id=7 的服务仅使用了 1 次。正如 Calc table 所示,通常,在服务 #7 上使用 raw material with id=11446 15ml 和 id=11448 15ml,在服务 #8 - raw material with id=11450 10毫升。即,总使用量:原始 material 11446 - 15ml、11448 - 15ml 和 11450 - 20ml (2*10ml)。
我的查询如下所示:
select
i.id,
i.name as UsedRawMaterialName,
s.name as ServiceName,
ro.doc_id as ServiceDoc_id,
ri.cost as CostofRawMaterial,
sr.qnt as ServiceQnt, --used service quantity, for example, 2 times washing
sr.qnt*c.qnt as UsedRawMaterialQnt, --used service quantity*rawmaterial's used for 1 service
i.unit_k
from Inventory I, RecsOut ro, RecsIn ri, calc c, servrecs sr, serv s, Docs d, unit u,
where
d.doc_id= ro.doc_id and d.doc_id=sr.doc_id and d.doc_id=323 and
s.id=c.serv_id and sr.serv_id=c.serv_id and
c.rawmat_id=i.id and
ro.recsIn_id=ri.id and
i.unit_k=u.unit_k
我的目标是得到这样的结果:
但是,查询 returns 结果包含冗余记录和错误值,如下所示:
我的查询有什么问题?
更新 1: 我将“旧式 Join 语法”更改为“新式 Join 语法”,很容易发现错误出在“Join RecsOut ro on ro.id=i.id”子句中。 “New-style Join”确实比老式的更加直观。
select
i.id,
i.name as UsedRawMaterialName,
s.name as ServiceName,
ro.doc_id as ServiceDoc_id,
ri.cost as CostofRawMaterial,
sr.qnt as ServiceQnt, --used service quantity, for example, 2 times washing
sr.qnt*c.qnt as UsedRawMaterialQnt, --used service quantity*rawmaterial's used for 1 service
i.unit_k
from
Inventory I Join RecsOut ro on ro.id=i.id
Join RecsIn ri on ro.recsin_id=ri.id
Join calc c on c.rawmat_id=i.id
join ServRecs sr on sr.serv_id=c.serv_id
Join serv s on s.id=c.serv_id
Join doc d on d.doc_id=ro.doc_id and
d.doc_id=sr.doc_id and
d.doc_id=323
join unit u on i.unit_k=u.unit_k
@basti “New Style Join”的一个主要好处是每个 table 都可以在开发和测试期间一次引入一个。对于每个 table“加入”,很容易看出哪个关系产生了比您预期更多(或实际上更少)的记录
翻译您的代码后我发现某处可能有破损。感谢您回复评论 ...
from Inventory I
join RecsOut ro on ro.recsIn_id=ri.id
-- ??? join RecsIn ri, --- ??
join calc c on c.rawmat_id=i.id
join servrecs sr on sr.serv_id=c.serv_id
join serv s on s.id=c.serv_id
join Docs d on d.doc_id= ro.doc_id
and d.doc_id=sr.doc_id
and d.doc_id=323
join unit u on i.unit_k=u.unit_k
不要忘记拥抱内连接、左连接和外连接