4

次のような製品販売のテーブルがあります。

product   | amount   | ptype    | pdate      
p1        | 1.00     | sale     | 01/01
p1        | 2.00     | base     | 01/02
p2        | 1.50     | sale     | 02/03
p3        | 5.25     | base     | 10/10

そして、行ごとに1つの製品、金額の合計を表示するテーブルを作成したいと思います。製品が一意の場合はタイプを表示し、そうでない場合はタイプを「VAR」として表示し、製品が一意の場合は日付を表示し、そうでない場合は日付を表示しますヌルとして。結果は次のようになります。

product   | total    | ptype    | pdate      
p1        | 3.00     | VAR      | (NULL)
p2        | 1.50     | sale     | 02/03
p3        | 5.25     | base     | 10/10

次のことを行うことで、必要な結果を達成しています。

SELECT DISTINCT product
,(SELECT SUM(amount) FROM T as b GROUP BY b.product HAVING a.product = b.product ) as total
,(SELECT CASE WHEN COUNT(*) = 1 THEN a.ptype  ELSE 'VAR' END from T as b GROUP BY b.product HAVING a.product = b.product) as ptype
,(SELECT CASE WHEN COUNT(*) = 1 THEN a.pdate  ELSE NULL END from T as b GROUP BY b.product HAVING a.product = b.product) as pdate
FROM T as a

しかし、同じ結果を達成するより効率的な方法があるかどうかを知りたいです。

4

3 に答える 3

6

サブクエリやインライン ビューを使用する必要はありません。データベース エンジンの精巧さによっては、これらの構造がパフォーマンスに悪影響を及ぼす可能性があります。

これがあなたが要求したものです。最も原始的な SQL エンジンでも、テーブルを 1 回スキャンするだけで確実に結果が得られるはずです。

select product,
       sum(amount) as amount,
       case when count(*)=1 then min(ptype) else 'VAR' end as ptype,
       case when count(*)=1 then min(pdate) else null end as pdate
  from T
 group by product

以下は、あなたが要求したものと正確には一致しませんが、実際に探しているものにより近いと思います。集計を構成する複数の異なる値がある場合、ptype を VAR として、または pdate を NULL としてのみ報告します。

ptype と pdate の両方が null でない場合でも、一重項集計を識別できるように、pcount 列を追加しました。

select product,
       sum(amount) as amount,
       count(*) as pcount,
       case when count(distinct ptype)=1 then min(ptype) else 'VAR' end as ptype,
       case when count(distinct pdate)=1 then min(pdate) else null end as pdate
  from T
 group by product
于 2012-06-29T04:26:58.557 に答える
1

これを主要なデータベース (SQL Server など) に対して実行している場合、クエリ オプティマイザーが最適化のほとんどを自動的に処理します。そうは言っても、単一の group by を持つ内部クエリを使用すると、これを非常に簡単に行うことができます。これは機能し、遊ぶことができる例です:

http://sqlfiddle.com/#!3/f2e05/19/1

于 2012-06-29T04:30:08.467 に答える
-1

このコードを試してください:

SELECT DISTINCT product, x.total,
IF(COUNT(x.ptype) > 1, 'VAR', x.ptype) AS ptype,
IF(COUNT(x.pdate) > 1, NULL, x.pdate) AS pdate
FROM (SELECT DISTINCT product, SUM(amount) AS total, ptype, pdate FROM table GROUP BY product) AS x
JOIN table ON x.product = table.product
GROUP BY x.product;

うまくいけばうまくいきます。

于 2012-06-29T04:18:26.593 に答える