sql语句现有material_type物料分类表,material物料表,物料分类表material_type包含id,物料分类名称type_name,物料表包含id,物料名称name,物料分类的material_type_id,根据物料分类下的物料数量统计出各物料分类的占比
时间: 2024-06-05 11:07:36 浏览: 142
可以使用以下 SQL 语句进行统计:
SELECT t.type_name, COUNT(*) AS num, COUNT(*) / SUM(COUNT(*) ) OVER() * 100 AS percentage
FROM material_type t
LEFT JOIN material m ON t.id = m.material_type_id
GROUP BY t.type_name;
这个 SQL 语句会左连接两个表,以物料分类表为主表,统计出每个物料分类下的物料数量以及各自占据的百分比。最终结果会包括物料分类名称、物料数量、百分比三个字段。
相关问题
SELECT TOP 10 tag_id, tag_code, RFID, storage_stock_id, material_id, material_code, data_status, material_name, spec, model, factory_name, supplier_id, supplier_name, lot_number, valid_to_date, material_type, pack_id, unit_code, unit, pack_type, sub_unit_code, sub_unit, dept_name, sub_conversion_rate, conversion_rate, status, original_barcode, udi, create_time, min_material_code, insurance_id, insurance_spec_code, order_in_code, order_in_id, is_used FROM ( SELECT ROW_NUMBER ( ) OVER ( ORDER BY create_time DESC ) PAGE_ROW_NUMBER, tag_id, tag_code, RFID, storage_stock_id, material_id, material_code, data_status, material_name, spec, model, factory_name, supplier_id, supplier_name, lot_number, valid_to_date, material_type, pack_id, unit_code, unit, pack_type, sub_unit_code, sub_unit, dept_name, sub_conversion_rate, conversion_rate, status, original_barcode, udi, create_time, min_material_code, insurance_id, insurance_spec_code, order_in_code, order_in_id, is_used FROM ( SELECT mt.tag_id, mt.tag_code, mt.RFID, mt.storage_stock_id, mss.material_id, mss.material_code, mt.data_status, mi.material_name, mi.spec, mi.model, mi.factory_name, mss.supplier_id, mss.supplier_name, mt.lot_number, mt.valid_to_date, mi.material_type, mss.pack_id, mss.unit_code, CASE WHEN mi.material_type = 'MAT-GZ' THEN mp.pack_unit ELSE mt.unit + '(' + CONVERT ( VARCHAR ( 10 ), mtd.quantity ) + mtd.unit + '/' + mt.unit + ')' END AS unit, mp.pack_type, mss.sub_unit_code, mss.sub_unit, sd.dept_name, mp.sub_conversion_rate, mp.conversion_rate, mt.status, mt.original_barcode, mt.udi, mt.create_time, mi.min_material_code, mi.insurance_id, mi.insurance_spec_code, mssd.order_in_code, mssd.order_in_id, mt.is_used FROM material_tag mt LEFT JOIN material_tag_detail mtd ON mtd.tag_id = mt.tag_id LEFT JOIN material_storage_stock_detail mssd ON mssd.stock_detail_id = mtd.stock_detail_id LEFT JOIN material_storage_stock mss ON mss.stock_id = mssd.storage_stock_id LEFT JOIN material_pack mp ON mp.pack_id = mss.pack_id LEFT JOIN material_info mi ON mi.material_id = mss.material_id LEFT JOIN sys_dept sd ON sd.dept_id = mss.store_dept_id LEFT JOIN material_storage_stock_batch mssb ON mssb.stock_id = mss.stock_id LEFT JOIN order_in oi ON oi.order_in_code = mssb.batch_no LEFT JOIN material_pack mpk ON mpk.material_id = mss.material_id AND mpk.is_purchase_unit = 1 WHERE mt.hospital_id = 1 AND mss.store_dept_id = 367 ) AS PAGE_TABLE_ALIAS ) AS PAGE_TABLE_ALIAS WHERE PAGE_ROW_NUMBER > 0 ORDER BY PAGE_ROW_NUMBER查询速度19秒如何添加索引
首先需要确定哪些字段经常被用作查询条件或者作为排序字段,可以根据实际情况来选择适合的字段添加索引。根据这个 SQL 查询语句,可以考虑添加以下索引:
1. `hospital_id`、`store_dept_id`、`status`、`create_time`:这几个字段都经常被用作查询条件,可以添加组合索引来提高查询速度。
2. `material_id`、`material_code`、`min_material_code`:这几个字段都涉及到物料信息,如果物料信息表很大,可以考虑单独为它们添加索引。
3. `tag_id`、`tag_code`、`RFID`:这几个字段都涉及到标签信息,如果标签信息表很大,可以考虑单独为它们添加索引。
4. `storage_stock_id`、`stock_detail_id`、`batch_no`、`order_in_id`、`order_in_code`:这几个字段都涉及到库存信息和订单信息,如果这些表很大,可以考虑单独为它们添加索引。
需要注意的是,添加索引会占用一定的磁盘空间和内存,还会对插入、更新和删除操作产生一定的影响,因此需要谨慎考虑。同时,如果添加了过多的索引,也会影响数据库性能,因此需要根据实际情况进行权衡和调整。
帮我优化这个pgsql select info.pot_type_name,info.ttpw_addr as twlPortName,info.ttpw_addr_code as twlPortCode,info.tmr_material_name,info.ids --库存 ,(select sum(twl_leave_stock) from tms_whe_control where twl_material_id = any(STRING_TO_ARRAY(ids, ','))and twl_port_code=ttpw_addr_code and pot_type_name='合作港口') as twl_leave_stock from ( select port.pot_type_name,ttpw.ttpw_addr ,ttpw.ttpw_addr_code,tmrGroup.tmr_material_name, array_to_string( ARRAY( SELECT unnest(string_to_array(array_to_string(array_agg(distinct(tmr.tmr_id)),','), ',')) ), ',' ) ids from tms_transport_plan_work ttpw,tms_material_ref tmr,tms_material_ref tmrGroup,pub_ports port,tms_transport_plan plan where tmr.tmr_id=ttpw_tmr_id and tmr.parent_tmr_id=tmrGroup.tmr_id and port.pot_regcd=ttpw.ttpw_addr_code and port.pot_cnname=ttpw.ttpw_addr and plan.ttp_id=ttpw.ttpw_ttp_id and plan.ttp_waybill_status >0 AND ttpw.ttpw_plan_amount > 0 GROUP BY pot_type_name,ttpw_addr,ttpw_addr_code,tmrGroup.tmr_material_name ORDER BY ttpw_addr ) as info
这个 SQL 语句有一些可优化的地方,可以考虑以下几点:
1. 尽可能使用 JOIN 代替子查询。例如,第一个子查询中的 `pub_ports` 表可以通过 JOIN 进行连接。
2. 避免使用 `array_agg` 和 `unnest` 函数。这些函数需要进行大量的数组转换操作,非常耗费资源。如果可以,可以考虑使用其他方式将数组数据按逗号拼接。
3. 在使用 GROUP BY 时,只选择必要的列。不需要 GROUP BY 的列可以在外部查询中进行选择。
4. 对于多个表的连接,可以考虑使用合适的索引来提高查询性能。
下面是优化后的 SQL 语句:
```
SELECT
pot.pot_type_name,
ttpw.ttpw_addr AS twlPortName,
ttpw.ttpw_addr_code AS twlPortCode,
tmrGroup.tmr_material_name,
array_to_string(ids, ',') AS ids,
tms_whe.twl_leave_stock
FROM (
SELECT
ttpw_tmr_id,
array_agg(DISTINCT tmr.tmr_id) AS ids,
ttpw_addr,
ttpw_addr_code,
pot_type_name,
tmrGroup.tmr_material_name
FROM tms_transport_plan_work ttpw
JOIN tms_material_ref tmr ON tmr.tmr_id = ttpw.ttpw_tmr_id
JOIN tms_material_ref tmrGroup ON tmrGroup.tmr_id = tmr.parent_tmr_id
JOIN pub_ports pot ON pot.pot_regcd = ttpw.ttpw_addr_code AND pot.pot_cnname = ttpw.ttpw_addr
WHERE ttpw_plan_amount > 0
GROUP BY ttpw_tmr_id, ttpw_addr, ttpw_addr_code, pot_type_name, tmrGroup.tmr_material_name
) AS info
LEFT JOIN (
SELECT twl_material_id, twl_port_code, SUM(twl_leave_stock) AS twl_leave_stock
FROM tms_whe_control
WHERE pot_type_name = '合作港口'
GROUP BY twl_material_id, twl_port_code
) AS tms_whe ON tms_whe.twl_material_id = ANY(ids) AND tms_whe.twl_port_code = twlPortCode
ORDER BY twlPortName
```
这个 SQL 语句使用了 JOIN 来代替子查询,并避免了使用 `array_agg` 和 `unnest` 函数。同时,只选择必要的列进行 GROUP BY,使用合适的索引来优化查询性能。
阅读全文