如何将SQL写入标签数量直到它们用完为止?

时间:2016-02-08 21:02:40

标签: sql sql-server sql-server-2012

我想使用指定的标签(参见quantity table表)标记数量(在label assignment中),直到数量变为0.然后我知道我已完成标记该特定ID。

label assignment表格如下:

ID  |  Label | Quantity
 1      aaa      10
 1      bbb      20
 2      ccc      20

我的quantity table

ID  |  Total Quantity
 1       60
 2       20

我希望得到以下结果:

ID  |   Label    | Quantity 
 1       aaa         10       (read from reference table, remaining 50)
 1       bbb         20       (read from reference table, remaining 30)
 1       [NULL]      30       (no label in reference table, remaining 0)
 2       ccc         20       (read from reference table, remaining 0)

3 个答案:

答案 0 :(得分:1)

您可以通过简单的JOINUNION操作来执行此操作,以便包含“未涵盖”'量:

SELECT la.ID, la.Label, la.Quantity
FROM label_assignment AS la
INNER JOIN quantity AS q ON la.ID = q.ID

UNION 

SELECT q.ID, NULL AS Label, q.TotalQuantity - la.TotalQuantity  
FROM quantity AS q
INNER JOIN (
   SELECT ID, SUM(Quantity) AS TotalQuantity
   FROM label_assignment
   GROUP BY ID
) AS la ON q.ID = la.ID AND q.TotalQuantity > la.TotalQuantity 

Demo here

答案 1 :(得分:1)

    // ...
    while (menuItem != 0) {
        try {
            menuItem = menu();
            switch (menuItem) {
            // ...

子查询计算一组用完的标签以及之后剩余的项目数。如果在最后一个标签之后剩余任何数量,那么我们需要在结果集中插入一行。为此,我加入了一个双元素表,但只有当我们位于最后一个标签并且剩余数量时,连接条件才为真。这可能是一种令人困惑的方式,我们可以将来自George的答案的UNION与我的子查询结合起来,以避免使用此溢出表。

以下是更改(可能更可取)的查询:

DECLARE @PerLabelQuantity TABLE(Id int, Label varchar(10), Quantity int);
INSERT INTO @PerLabelQuantity 
VALUES (1, 'aaa', 10), (1, 'bbb', 20), (2, 'ccc', 20);

DECLARE @QuantityRequired TABLE(Id int, TotalQuantity int);
INSERT INTO @QuantityRequired
VALUES (1, 60), (2, 20);

SELECT t.Id,
       CASE WHEN o.Overflowed = 1 THEN NULL ELSE t.Label END AS Label, 
       CASE WHEN o.Overflowed = 1 THEN t.QuantityStillNeeded 
            WHEN t.QuantityStillNeeded < 0 THEN t.Quantity + t.QuantityStillNeeded 
            ELSE t.Quantity END AS Quantity
FROM (
    SELECT p.Id, p.Label, p.Quantity,
        MAX(p.Label) OVER (PARTITION BY p.Id) AS LastLabel, 
        r.TotalQuantity - SUM(p.Quantity) 
            OVER (PARTITION BY p.Id 
                  ORDER BY Label 
                  ROWS UNBOUNDED PRECEDING) AS QuantityStillNeeded
    FROM @PerLabelQuantity p
    INNER JOIN @QuantityRequired r ON p.Id = r.Id) t
INNER JOIN (VALUES (0), (1)) o(Overflowed) 
    ON t.LastLabel = t.Label AND t.QuantityStillNeeded > 0 OR Overflowed = 0
WHERE t.QuantityStillNeeded > -t.Quantity; -- Remove this if you want labels with 
                                           -- 0 quantity used, but you'll need to tweak 
                                           -- the CASE expression for Quantity

答案 2 :(得分:0)

最简单的答案我认为,在从其他答案中获得想法之后:只需为缺少的金额创建一个“FAKE”标签:

Options -MultiViews
RewriteEngine On
RewriteBase /

RewriteRule ^(me)?/?$ profile_page.php [L,NC]
RewriteRule ^profile(?:_page)?/([\w-]+)/?$ profile_page.php?u=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/?$ profile_page.php?u=$1 [L,QSA]