3

私はSFでこの問題を見てきましたが、私は初心者なので、揚げた頭脳をそれらの周りに置くことができません. これが繰り返しのように感じられる場合は、ご容赦ください。

私のサンプルテーブル

--------------------------
ID | サプライヤー | 数量
--------------------------
1 1 2
2 1 2
3 2 5
4 3 2
5 1 3
6 2 4

特定のサプライヤーIDの降順で、「QTY」の累積合計が5以上である行「UNTIL」を取得する必要があります。

この例では、サプライヤー 1 の場合、ID が 5 と 2 の行になります。

    Id - 一意の主キー
    仕入先 - 外部キー、仕入先情報用の別のテーブルがあります。
    数量 - ダブル
4

5 に答える 5

2

きれいではありませんが、これで十分だと思います。おそらく、扱いにくいものの基礎になる可能性があります。初めて変数を初期化するためだけに「偽の」INNER JOIN を使用していることに注意してください。それは他の役割を果たしません。

SELECT ID,
       supplier,
       qty,
       cumulative_qty
FROM
(
    SELECT
        ID,
        supplier,
        qty,
        -- next line keeps a running total quantity by supplier id
        @cumulative_quantity := if (@sup <> supplier, qty, @cumulative_quantity + qty) as cumulative_qty,
        -- next is 0 for running total < 5 by supplier, 1 the first time >= 5, and ++ after
        @reached_five := if (@cumulative_quantity < 5, 0, if (@sup <> supplier, 1, @reached_five + 1)) as reached_five,
        -- next takes note of changes in supplier being processed
        @sup := if(@sup <> supplier, supplier, @sup) as sup
    FROM
    (
        --this subquery is key for getting things in supplier order, by descending id
        SELECT *
        FROM `sample_table`
        ORDER BY supplier, ID DESC
     ) reverse_order_by_id
    INNER JOIN
    (
        -- initialize the variables used to their first ever values
        SELECT @cumulative_quantity := 0, @sup := 0, @reached_five := 0
    ) only_here_to_initialize_variables
) t_alias
where reached_five <= 1 -- only get things up through the time we first get to 5 or above.
于 2013-01-22T04:54:56.717 に答える
0
SELECT x.* 
  FROM supplier_stock x 
  JOIN supplier_stock y  
    ON y.supplier = x.supplier 
   AND y.id >= x.id 
 GROUP 
    BY supplier
     , id 
HAVING SUM(y.qty) <=5;
于 2013-01-22T04:02:51.517 に答える
0

これはカーソルに関する大まかなデモです。役立つかもしれません。

CREATE TABLE #t
(
    ID       INT IDENTITY,
    Supplier INT,
    QTY      INT
);


TRUNCATE TABLE #t;

INSERT  INTO #t (Supplier, QTY)
VALUES         (1, 2),
(1, 2),
(2, 5),
(3, 2),
(1, 3);

DECLARE @sum AS INT;

DECLARE @qty AS INT;

DECLARE @totalRows AS INT;

DECLARE curSelectQTY CURSOR
    FOR SELECT   QTY
        FROM     #t
        ORDER BY QTY DESC;

OPEN curSelectQTY;

SET @sum = 0;

SET @totalRows = 0;

FETCH NEXT FROM curSelectQTY INTO @qty;

WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sum = @sum + @qty;
        SET @totalRows = @totalRows + 1;
        IF @sum >= 5
            BREAK;
    END

SELECT   TOP (@totalRows) *
FROM     #t
ORDER BY QTY DESC;

CLOSE curSelectQTY;

DEALLOCATE curSelectQTY;
于 2013-01-22T03:06:05.883 に答える
0

標準 SQL には「現在の行番号」という概念がないため、これはカーソルと呼ばれるものを使用してのみ実装できます。カーソルを使用してコードを記述することは、他の言語で for ループを使用してコードを記述することに似ています。

カーソルの使用方法の例を次に示します。

http://dev.mysql.com/doc/refman/5.0/en/cursors.html

于 2013-01-22T02:38:31.447 に答える
0

これはどう?2 つの変数の使用。

SQLFIDDLE デモ

クエリ:

set @tot:=0;
set @sup:=0;

select x.id, x.supplier, x.ctot
from (
select id, supplier, qty,
@tot:= (case when @sup = supplier then
@tot + qty else qty end) as ctot,
@sup:=supplier
from demo
order by supplier asc, id desc) x
where x.ctot >=5
;

| ID | SUPPLIER | CTOT |
------------------------
|  2 |        1 |    5 |
|  1 |        1 |    7 |
|  3 |        2 |    5 |
于 2013-01-22T02:58:25.330 に答える