我一直在苦苦寻求一个查询,我不确定它是否可能在纯sql中或需要由php支持。
基本上我想生成一份订单报告,列出已在系统中超额预订的产品。
表格结构:
订单
id int
bookingStart DATETIME
bookingEnd DATETIME
ORDER_LINES
id int
qty int
product_id int
booking_id int
产品
id int
stock int
订单可以包含多个具有相同产品的行。因此,订单上的每个产品都需要有一个SUM。有没有人对最佳方法有任何建议?
我已经尝试使用子查询在特定时间间隔内循环,但它没有考虑不同预订之间的重叠,如果可以通过单个查询完成,那么就有点卡在这里:
SELECT (SELECT SUM(lin2.qty) FROM booking_lines lin2,orders b2
WHERE
lin2.product_id=e.id AND
b2.id=lin2.booking_id AND (
(b2.bookingStart BETWEEN b1.bookingStart AND b1.bookingEnd) OR
(b2.bookingEnd BETWEEN b1.bookingStart AND b1.bookingEnd) OR
(b2.bookingStart < b1.bookingStart AND b2.bookingEnd > b1.bookingEnd)
) as booked SUM(lin1.qty)
FROM orders b1
LEFT JOIN order_lines lin1 ON b1.id=lin1.booking_id
LEFT JOIN products e ON e.id=lin1.product_id
(
(b1.bookingStart BETWEEN '$s' AND '$e') OR
(b1.bookingEnd BETWEEN '$s' AND '$e') OR
(b1.bookingStart < '$s' AND b1.bookingEnd > '$e')
)
GROUP BY b1.id,lin1.product_id
问题所在 如果我们的产品x的库存为10。
订单1已预订3个产品x 订单2已预订了5个产品x 订单3已预订了8个产品x
以下行表示预订的时间跨度
__ _ ___ 订单1 x:3 < EM> _ __ _
_ __ 订单2 x:5 _ __ _ _ < /强>
_ __ _ __ _ ___ 订单3 x:8 < EM> _ __ _ __
__ 订单4 x:2 _
所以只有当3个订单重叠时,产品x实际上是超量预订的,我无法弄清楚如何创建一个能够检测到它的查询。
答案 0 :(得分:1)
我没有要测试的MySql实例,但你尝试过这样的事情:
select p.id, p.stock, t.bookedQty
from products as p
inner join (
select ol.product_id, sum(ol.qty) as bookedQty
from order_lines as ol
inner join orders as o on ol.booking_id = o.id
where o.bookingStart between '2013-06-10' and '2013-06-11'
and t.bookedQty > p.stock
group by ol.product_id) as t
- 参见评论1 -
我在下面的tftd回答中使用了SqlFiddle模式(谢谢)。这应该每天生成下一个超额预订,预订数量和库存数量的100个:
SELECT
date,
p.product_id,
sum(ol.qty) AS total_booked,
p.stock AS available
FROM (
SELECT c.date
FROM
(SELECT curdate() + interval (a.a + (10 * b.a)) DAY AS date
FROM
(SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS a CROSS
JOIN
(SELECT 0 AS a
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9) AS b
) AS c
WHERE c.date >= curdate() AND c.date < DATE_ADD(curdate(), INTERVAL 100 DAY)
) AS gendates
INNER JOIN orders AS o ON o.bookingStart <= gendates.date AND o.bookingEnd > gendates.date
INNER JOIN order_lines AS ol ON o.order_id = ol.order_id
INNER JOIN products AS p ON ol.product_id = p.product_id
GROUP BY gendates.date, p.product_id, p.stock
HAVING total_booked > p.stock
答案 1 :(得分:1)
表格结构
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
stock INT
) ENGINE=InnoDB;
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
bookingStart DATETIME,
bookingEnd DATETIME
) ENGINE=InnoDB;
CREATE TABLE order_lines (
line_id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
product_id INT,
qty INT NOT NULL DEFAULT 0,
CONSTRAINT FOREIGN KEY(order_id) REFERENCES orders(order_id) ON DELETE RESTRICT,
CONSTRAINT FOREIGN KEY(product_id) REFERENCES products(product_id) ON DELETE RESTRICT
) ENGINE=InnoDB;
INSERT INTO products(name, stock) VALUES('Product 1', 8);
INSERT INTO products(name, stock) VALUES('Product 2', 14);
INSERT INTO products(name, stock) VALUES('Product 3', 25);
INSERT INTO orders(bookingStart,bookingEnd) VALUES(NOW(), (NOW() + INTERVAL 2 HOUR));
INSERT INTO orders(bookingStart,bookingEnd) VALUES(NOW(), (NOW() + INTERVAL 3 HOUR));
INSERT INTO orders(bookingStart,bookingEnd) VALUES(NOW(), (NOW() + INTERVAL 4 HOUR));
INSERT INTO order_lines(order_id, product_id, qty) VALUES(1, 1, 2);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(1, 1, 8);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(2, 2, 5);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(2, 2, 10);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(3, 3, 2);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(3, 3, 8);
INSERT INTO order_lines(order_id, product_id, qty) VALUES(3, 3, 10);
获取超量预订产品:
SELECT
products.*,
SUM(order_lines.qty) as sum_qty
FROM products
LEFT JOIN order_lines ON order_lines.product_id = products.product_id
LEFT JOIN orders ON orders.order_id = order_lines.order_id
WHERE orders.bookingStart >= '2013-06-12'
AND orders.bookingEnd <= '2013-06-14'
GROUP BY order_lines.order_id, order_lines.product_id
HAVING sum_qty > products.stock
将返回Product 1
和Product 2
,因为qty
中order_lines
的总和大于products.stock
(这可能是产品的可用数量) ?)。