Tot*_*son 5 mysql sql inventory dbexpress sqlfiddle
我们正在为名为 readoutprobes 和 readoutprobekits 的项目创建一个库存系统。下面的模式使用items和itemkits两个词进行了简化。
一个物品包,是一个或多个物品的预定义集合,即一个套件。在套件中,特定类型的物品只能出现一次。一个套件,通常包含约 40 件物品。套件中物品的定义由itemkit_item表捕获。套件的库存记录在itemkit_containers表中。
itemkit_container不跟踪物理项目容器。相反,它假设使用一组物理项目正确地“组装”了一个物理项目包,但我们不知道是哪些。填充时,itemkit_containers 记录中的“填充”字段设置为 true。
物品的库存由item_containers表跟踪。它的存在由容器体积监控。当体积为 0 时,容器被认为是空的。
从item_container表中获取特定物品的体积> 0的物理物品容器的数量,对于套件也是如此
我们希望获得每个项目的“保留计数”编号,以反映套件库存。
例如,假设我们有一个名为 A 的项目,其计数为 42。如果我们正在创建一个包含名为 A 的项目和相应的 itemkit_container 的 itemkit,我们希望“reserved”的计数为 1,对于 item一种。
项目的“主查询”如下所示:
SELECT items.*,
ic.item_count
FROM items
LEFT JOIN (
SELECT p.id, COUNT(*) item_count, ic.item_id
FROM items AS p, item_containers AS ic
WHERE p.id = ic.item_id AND ic.volume > 0
GROUP BY p.id
) AS ic
ON ic.item_id = items.id
GROUP BY items.id
ORDER BY items.id;
Run Code Online (Sandbox Code Playgroud)
项目表中的数据:
item_containers 表中的数据:
itemkits 表中的数据:
itemkit_item 表中的数据:
itemkit_containers 中的数据:
可以观察到,物品包及其库存的唯一记录包含物品 ID = {1,3}
这个问题是为了找出在任何一个时间点如何查询“空闲”(或保留)物理项目的数量,即 item_containers 存货。
上面的查询,返回这个结果:
我们需要一个额外的字段,指示每个项目的“保留”计数,反映项目和项目包的实际库存状态。
对于上面的数据,这将是
A -> Reserved = 1
B -> Reserved = 0
C -> Reserved = 1
D -> Reserved = 0
Run Code Online (Sandbox Code Playgroud)
创建和填充上述表格的 db fiddle 在这里: DB Fiddle
我们使用的是 MySQL 8.0。
注意:下面的答案接近正确。但是,它不会将 item_containers(实际库存)与 itemkit_container 记录相关联,而是与 itemkit 记录相关联。通过将 itemkit_containers 表中的填充字段切换为“0”,这一点变得清晰。IE:
即使套件不再填充,输出也会显示相同的“保留”计数。在这种情况下,保留应等于“0”。这是这种情况的小提琴:Fiddle where Reserved should be all '0'
感谢您提供如此详细的描述和所有必要的示例数据。
正如您已经在查询中尝试过的那样,您可以通过连接 items 和 item_containers 表来获得具有数量的项目。为了计算免费或保留的物品,您需要左连接 itemkit_containsers 表,因为套件中物品的库存存储在那里。因此,只需计算 itemkit_containers 中任何商品的数量,即可获得预留数量,并从 item_containsers 表的 item_count 中减去它,即可得到该商品的免费数量。
架构和插入语句:
CREATE TABLE `items` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'oligoname + fluorophore wavelength',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='ReadoutProbes for mFISH Survey';
CREATE TABLE `item_containers` (
`id` int NOT NULL AUTO_INCREMENT,
`item_id` int NOT NULL COMMENT 'content of tube',
`volume` float(12,2) NOT NULL COMMENT 'volume in micro liter (uL)',
PRIMARY KEY (`id`),
KEY `fk_item_containers_items` (`item_id`),
CONSTRAINT `fk_item_containers_items` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=764 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Physical tubes received from vendor';
CREATE TABLE `itemkits` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `Unique` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1030 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='A readout kit is a collection of readouts, and defined in a codebook';
CREATE TABLE `itemkit_containers` (
`id` int NOT NULL AUTO_INCREMENT,
`itemkit_id` int NOT NULL,
`populated` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Field used for checking in checking out a tray',
PRIMARY KEY (`id`),
KEY `fk_readoutkit_tray_readoutkits` (`itemkit_id`),
CONSTRAINT `fk_readoutkit_tray_readoutkits` FOREIGN KEY (`itemkit_id`) REFERENCES `itemkits` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1027 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Physical readoutkit_tray';
CREATE TABLE `itemkit_item` (
`itemkit_id` int NOT NULL,
`item_id` int NOT NULL,
UNIQUE KEY `Uniqueness` (`itemkit_id`,`item_id`),
KEY `fk_readoutkit_item_readout_probes` (`item_id`),
CONSTRAINT `fk_readoutkit_item_readout_probes` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`),
CONSTRAINT `fk_readoutkit_item_readoutkits` FOREIGN KEY (`itemkit_id`) REFERENCES `itemkits` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='associations table for definition of a readout kit';
insert into `items`(`id`,`name`) values
(1,'A'),
(2,'B'),
(3,'C'),
(4,'D');
insert into `itemkits`(`id`,`name`) values
(1,'Kit_1');
insert into `itemkit_containers`(`itemkit_id`,`populated`) values
(1,0);
insert into `itemkit_item`(`itemkit_id`,`item_id`) values
(1,1),
(1,3);
insert into `item_containers`(`item_id`,`volume`) values
(1,1.00),
(2,1.00),
(3,1.00),
(4,1.00),
(1,1.00);
Run Code Online (Sandbox Code Playgroud)
询问:
select i.id,i.name,sum(ic.volume) as total_volume,
sum(coalesce(ii.item_count,0)) as Reserved
from items i inner join item_containers ic on i.id=ic.item_id
left join (select item_id,count(*) as item_count from itemkit_containers ic
inner join itemkit_item i on ic.itemkit_id =i.itemkit_id and ic.populated=1
group by item_id) ii
on i.id=ii.item_id
group by i.id,i.name
order by i.id,i.name
Run Code Online (Sandbox Code Playgroud)
输出:
| ID | 姓名 | 总容积 | 预订的 |
|---|---|---|---|
| 1 | A | 2.00 | 0 |
| 2 | 乙 | 1.00 | 0 |
| 3 | C | 1.00 | 0 |
| 4 | D | 1.00 | 0 |
db<在这里小提琴
Db-Fiddle 包含已填充和未填充的 itemkit_containsers:
选择查询(示例数据):
SELECT * from items;
SELECT item_id, volume from item_containers;
SELECT * FROM itemkits;
SELECT itemkit_id, populated FROM itemkit_containers;
SELECT * FROM itemkit_item;
Run Code Online (Sandbox Code Playgroud)
输出:
| ID | 姓名 |
|---|---|
| 1 | A |
| 2 | 乙 |
| 3 | C |
| 4 | D |
| 商品编号 | 体积 |
|---|---|
| 1 | 1.00 |
| 2 | 1.00 |
| 3 | 1.00 |
| 4 | 1.00 |
| 1 | 1.00 |
| ID | 姓名 |
|---|---|
| 1 | 套件_1 |
| 2 | 套件_2 |
| itemkit_id | 人口稠密的 |
|---|---|
| 1 | 0 |
| 2 | 1 |
| itemkit_id | 商品编号 |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 1 | 3 |
询问:
select i.id,i.name,sum(ic.volume) as total_volume,
sum(coalesce(ii.item_count,0)) as Reserved
from items i inner join item_containers ic on i.id=ic.item_id
left join (select item_id,count(*) as item_count from itemkit_containers ic
inner join itemkit_item i on ic.itemkit_id =i.itemkit_id and ic.populated=1
group by item_id) ii
on i.id=ii.item_id
group by i.id,i.name
order by i.id,i.name
Run Code Online (Sandbox Code Playgroud)
输出:
| ID | 姓名 | 总容积 | 预订的 |
|---|---|---|---|
| 1 | A | 2.00 | 0 |
| 2 | 乙 | 1.00 | 1 |
| 3 | C | 1.00 | 0 |
| 4 | D | 1.00 | 0 |
db<在这里小提琴
| 归档时间: |
|
| 查看次数: |
281 次 |
| 最近记录: |