8

タイトルにあるように、同じ列にある2つの値を互いに分割したいと思います。例えば

    A             B              C            D
  Shirts         2011           85            0
  Shirts         2012           92      percent change from 2011 to 2012
  Shirts         2013          100      percent change from 2012 to 2013
  Pants          2011           31            0
  Pants          2012           42      percent change from 2011 to 2012
  Pants          2013           55      percent change from 2012 to 2013
  Jacket         2011           10            0
  Jacket         2012           16      percent change from 2011 to 2012
  Jacket         2013           18      percent change from 2012 to 2013

この例では、列Dは列Cから派生し、2012の値が2011から減算され、次に100を掛けてパーセントを取得します。

クエリを設定する方法がわかりません。一連のサブクエリを実行しようとしましたが、それらをリンクする方法がわかりませんでした。どんな助けでも大歓迎です。

4

7 に答える 7

2

これがあなたが求めているものを手に入れるためのオプションです

SELECT t1.a, t1.b, t1.c,
    CASE WHEN t2.c IS NULL THEN 0 ELSE t1.c - t2.c END AS d,
    CASE WHEN t2.c IS NULL THEN 0 ELSE (1.0 * t1.c - t2.c) / t1.c * 100.0 END AS pct
FROM t t1
LEFT OUTER JOIN t t2 ON t1.a = t2.a
    AND t1.b = t2.b + 1

SQLフィドルの例

于 2013-03-14T03:31:07.620 に答える
2

これは、自己参加で実現できます。

SELECT curr.ClothingType, curr.SalesYear, curr.NumberSold
   , COALESCE((CAST((curr.NumberSold - prev.NumberSold) AS NUMERIC(5,2)) / prev.NumberSold) * 100, 0) AS PercentChange
FROM #Clothes AS curr
LEFT JOIN #Clothes AS prev ON curr.ClothingType = prev.ClothingType
   AND curr.SalesYear = prev.SalesYear + 1

SQLフィドルの例

于 2013-03-14T04:10:29.067 に答える
1

要件を正しく理解している場合は、再帰cteを使用して結果を得ることができます。これはROW_NUMBER()、列Aを使用して(グループ化して)パーティション化します。

この方法は、列Bで連続した年を保証できない場合に最適に機能します。常に連続した年がある場合は、bobsが最良の代替手段を提供します。

with cte as (
  select A, B, C, 
    ROW_NUMBER() OVER (PARTITION BY A ORDER BY B) rn
  from yourtable
  ),
recursive_cte as (
  select A, B, C, 0 prc
  from cte
  where rn = 1
  union all
  select y.A, y.B, y.C, y.C-c.C prc
  from cte y 
    join cte c on y.a=c.a and y.rn=c.rn+1
)
select * 
from recursive_cte
order by a, b

SQLフィドルデモ

これにより、各年と列Aでグループ化された前の年との差が返されます。簡単にするために2番目のCTEを使用します。実際のパーセントを変更したい場合は、上記の式を更新してください。

- 編集

成長率を探しているように思われるので、代わりにyC-cCprcを次の式に置き換えてみてください。

cast(y.C as decimal(10,2))/cast(c.C as decimal(10,2))

CASTデータ型が整数の場合に使用します。

于 2013-03-14T03:21:46.923 に答える
1

私はShivanに同意しますが、それはPHPなしでそれを行う方法がわからないからです。PHPの場合は、2つの合計を取得し、計算を実行して、回答を含むクエリを送り返すだけです。

それはあなたの数学が間違っている より重要な部分なので、これも必ず読んでください。(Shirts2011 - Shirts2012) * 100変化率はわかりません。それはあなたに与えるだけです100 times the difference of the two(実際には、あなたの言い回しに基づく負の違い)。数学的には、次のようにします。

((Item2012-Item2011)/Item2011)*100

外部のparensは必要ないことは知っていますが、読みやすくなっています。変化率は、2つの差の初期値に対する比率の100倍と同じです。

PHPコードを追加するために編集されました。

PHPは粗雑に見えますが、仕事は終わりです。

$conn = new PDO(HOST:DATABASE, USERNAME, PASSWORD);
    $query = "SELECT A, B, C FROM yourTable";
    $st = $conn->prepare($query);
    $st->execute();

$list = array();
while($row = $st->fetch(PDO::FETCH_ASSOC))
    $list[] = $row;

$fill = array();
for($i=1; $i<count($list); $i++)
    if($list[$i]['A'] == $list[$i-1][A])
        $fill[] = $array('A' => $list[$i]['A'],
                         'B' => $list[$i]['B'],
                         'D' => ($list[$i]['C']-$list[$i-1]['C'])/$list[$i-1]['C']*100);

$update = new PDO(HOST:DATABASE, USERNAME, PASSWORD);
    for($i=0; $i<count($fill); $i++){
        $query = "UPDATE yourTable SET D = " . $fill[$i]['D'] . " WHERE A = " . $fill[$i]['A'] . " AND B = " . $fill[$i]['B'];
        $st = $update->prepare($query);
        $st->execute();
    }

2011D列=0のテーブルを初期化するだけです。

UPDATE yourTable SET D = 0 WHERE B = 2011;

そして、炎が始まる前に、foreachが機能していたことを私は知っています。の標準の方が見栄えが良いと思います(2011年の最初の値をスキップできます)。

于 2013-03-14T03:17:17.043 に答える
0

これを試して:

select Y2013.*, Y2012.C, Y2013.C, Y2013.C/Y2011.C
from (
  select * from data where B = year(getdate())
) Y2013
left join (
  select * from data where B = year(getdate()) - 1
) Y2012 on Y2012.A = Y2013.A
left join (
  select * from data where B = year(getdate()) - 2
) Y2011 on Y2011.A = Y2012.A
 and  Y2011.A = Y2013.A
于 2013-03-14T03:23:42.130 に答える
0

これを試して:

SELECT t1.type A, t1.year B, t1.value C,
IF(
  EXISTS(
    SELECT 1 FROM table t2 WHERE t1.type = t2.type AND t1.year = (t2.year - 1)
  ),
  ((SELECT t3.year FROM table t3 WHERE t1.type = t3.type AND t1.year = (t3.year - 1)) - t1.year)/t1.year,
  0
) D
FROM table t1

あまり効率的ではありませんが、実行できます。

于 2013-03-14T03:14:27.680 に答える
0

あなたもこれを試すことができます:

UPDATE mytable t1
  INNER JOIN mytable t2 
  ON t1.A = t2.A AND t2.B = t1.B - 1
SET t1.D = ((t1.C - t2.C)  / t2.C) * 100;

フィドルを参照してください。

Dのデフォルトとしてすでに0があると仮定します。そうでない場合は、このクエリを実行する前に、すべての行で0に設定してください。

于 2013-03-14T03:38:01.987 に答える