试图找出用于平衡儿童玩具的SQL查询。
在Children
表中,列为:
ID INT, <br>
FNAME NCHAR(50), <br>
LNAME NCHAR(50), <br>
NumberofToys INT
然后在Toys
表中我们有:
ID INT, <BR>
ToyName NCHAR(50) <BR>
ChildrenID INT -->This is a FK to the Children table
所以这里的关系是一对多(一个孩子可以有0到多个玩具)。
平衡孩子们的玩具意味着以下几点:
如果有少量儿童和数量的玩具,那么每个儿童应该有(m / n)玩具
如果有少量儿童和n + 1个玩具,那么每个儿童将拥有(m / n)玩具,其中一个孩子在桌子上有n + 1个玩具。
如果有少量儿童和n-1个玩具,那么每个儿童将拥有(m / n)玩具,其中一个孩子在桌子上有n-1个玩具。
如果已经平衡并且要从桌子上移走一个孩子,那么他们的玩具应该一次分配一个,直到他们的玩具份额完全分配。
如果已经平衡且其中一个儿童玩具已从玩具桌上移除,那么表中剩余的玩具应均匀重新分配
样品组(预平衡):
Children
ID FNAME LNAME NumberofToys
1 Bob Jones 3
2 Jenny James 5
Toys
ID ToyName ChildrenID
1 Bear 1
2 Train 2
3 Truck 2
4 Car 2
解决方案集:
Children
ID FNAME LNAME NumberofToys
1 Bob Jones 2
2 Jenny James 2
Toys
ID ToyName ChildrenID
1 Bear 1
2 Train 1
3 Truck 2
4 Car 2
我似乎无法在此获得正确的算法。将玩具添加到Toys表后,FK应该是第一个玩具数量最少的子ID。我尝试过的是:
DECLARE @ToyCount INT,
@ID INT
--This should take care of the balancing problem.
--Since Toys get added one at a time, just add to first Child
----with minimum amount of customers
SET @ToyCount = (SELECT MIN(NumberofToys) FROM Children)
--Store top id that has least amount of toys
SET @ID = (SELECT TOP 1 ID
FROM Children
WHERE @ToyCount=NumberofToys)
--This part is if a Child needs to be added to the table, NumberofToys would be originally 0
INSERT INTO Children (FNAME, LNAME, NumberofToys)
VALUES(@fname, @lname, 0);
--Increasing the number of toys for the ID we SET above
UPDATE Children
SET NumberofToys = NumberofToys + 1
WHERE ID=@ID
如果用户手动“平衡”孩子们玩具的数量,则需要进行平衡。上面添加的部分修复了任何新玩具,但不包括预先存在的玩具。有人可以帮帮我吗?我对预先存在的玩具的尝试如下:
DECLARE @ToyCount INT, @ToyCountMAX,
@ID INT, @IDMAX INT, @IDTarget INT
SET @ToyCount = (SELECT MIN(NumberofToys) FROM Children)
SET @ToyCountMAX = (SELECT MAX(NumberofToys) FROM Children)
--Store top id that has least amount of toys
SET @ID = (SELECT TOP 1 ID
FROM Children
WHERE @ToyCount=NumberofToys)
--Store top id that has most amount of toys
SET @IDMAX = (SELECT TOP 1 ID FROM Children WHERE @ToyCountMAX=NumberofToys)
--Take top id that has most amount of toys and set it to an ID that has least amount (I believe my problem is here. Can't get the syntax to set the top ChildrenID to the SELECT...on the right side of the = sign
UPDATE Toys
SET ChildrenID = (SELECT TOP 1 ChildrenID FROM Children WHERE NumberofToys=MIN(NumberofToys)
WHERE ChildrenID=@IDMAX
--Increasing the number of toys for the ID we SET above
UPDATE Children
SET NumberofToys = NumberofToys + 1
WHERE ID=@ID
--decreasing number of toys for the max ID
UPDATE Children
SET NumberofToys = NumberofToys - 1
WHERE ID=@IDMAX
答案 0 :(得分:1)
尝试以下商店流程,它应在任何阶段Toys
之间平衡Children
。
注意:从Children
表中删除子项时,您需要维护外键关系。因此,
Children
存储过程
CREATE PROCEDURE BalanceToys
AS
BEGIN
-- While there is imbalance between children
-- i.e. MAX toys owned minus MIN toys owned is greater than 1
WHILE((SELECT MAX(cnt)-MIN(cnt) FROM (
SELECT c.ID, SUM(CASE WHEN t.ID IS NOT NULL THEN 1 ELSE 0 END) Cnt
FROM Children c
LEFT JOIN Toys t ON c.ID = t.ChildrenID
GROUP BY c.ID) v) > 1)
BEGIN
-- We rebalance 1 toy at a time
-- the child with most toys will give 1 toy to the child with least toys
UPDATE TOP (1) Toys
SET ChildrenID = (SELECT TOP 1 c.ID
FROM Children c
LEFT JOIN Toys t ON c.ID = t.ChildrenID
GROUP BY c.ID
ORDER BY SUM(CASE WHEN t.ID IS NOT NULL THEN 1 ELSE 0 END))
WHERE ChildrenID = (SELECT TOP 1 c.ID
FROM Children c
LEFT JOIN Toys t ON c.ID = t.ChildrenID
GROUP BY c.ID
ORDER BY SUM(CASE WHEN t.ID IS NOT NULL THEN 1 ELSE 0 END) DESC)
-- Loop until all balanced
END
-- Update NumberofToys
UPDATE Children
SET NumberofToys = (SELECT COUNT(*) FROM Toys WHERE ChildrenID = Children.ID)
END
GO