7

出題される試験の練習問題をいくつか調べていますが、groupbyを完全に理解するのに問題があります。GROUPBYは次のように表示されます。結果セットを1つ以上の列でグループ化します。

私は次のデータベーススキーマを持っています

ここに画像の説明を入力してください

ここに画像の説明を入力してください

私の質問

SELECT orders.customer_numb, sum(order_lines.cost_line), customers.customer_first_name, customers.customer_last_name
FROM orders
INNER JOIN customers ON customers.customer_numb = orders.customer_numb
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb, order_lines.cost_line, customers.customer_first_name,     customers.customer_last_name
ORDER BY order_lines.cost_line DESC

理解するのに苦労していること
データ を単に使用GROUP BY orders.cost_lineしてcost_lineでグループ化できないのはなぜですか?

私が達成しようとしていること
私は最もお金を使った顧客の名前を達成したいと思います。私はこれを達成する方法を完全には理解していません。結合がどのように機能するかを理解していますが、customer_numbとcost_line(sum()を使用して支出額を計算する)を単純にGROUPBYできない理由を理解できないようです。私はいつも「GROUPBY式ではない」と思っているようです。誰かが私が間違っていることを説明できれば(答えを教えてくれるだけでなく)、それは素晴らしいことです。 GROUPbyを適切に使用するために必要です。

長いエッセイでごめんなさい、そして私が何かを逃したならば、私は謝罪します。どんな助けでも大歓迎です。

4

2 に答える 2

6

なぜcustomer_numbとcost_line(sum()を使用して支出額を計算する)を単純にグループ化できないのか、頭を悩ませているようには見えません。

group by customer_numbcustomer_numbがcustomerテーブルの行を一意に識別することがわかっている場合(customer_numbがプライマリキーまたは代替キーのいずれかであると想定)、任意の指定された値はとcustomers.customer_numbの値が1つだけになります。しかし、解析時には、Oracleはそれを認識していないか、少なくともそれを認識していないように動作します。そして、少しパニックに陥って、「シングルに複数の値がある場合はどうすればよいですか?」と書かれています。customers.customer_first_namecustomers.customer_last_namecustomer_numbcustomer_first_name

大まかに言うと、句内の式はselect句内の式を使用しgroup byたり、集計関数を使用したりできます。(ベーステーブルなどに依存しない定数やシステム変数も同様です。)そして、「使用する」とは、式または式の一部を意味します。したがって、名と名前でグループ化customer_first_name || customer_last_nameすると、有効な式にもなります。

主キーでグループ化されているようなテーブルがある場合customers、または一意のキーがありnull制約ではない列がある場合は、それらをgroup by句に安全に含めることができます。この特定の例では、group by customer.customer_numb, customer.customer_first_name, customer.customer_last_name.

また、グループの値がorder by1つではないため、最初のクエリのは失敗することに注意してください。句で列エイリアスを注文または使用して、そのorder_lines.cost_line上で注文することができますsum(order_lines.cost_line)selectalias

SELECT orders.customer_numb, 
    sum(order_lines.cost_line), 
    customers.customer_first_name, 
    customers.customer_last_name
FROM orders
INNER JOIN customers ON customers.customer_numb = orders.customer_numb
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb, 
    customers.customer_first_name, 
    customers.customer_last_name
ORDER BY sum(order_lines.cost_line)

また

SELECT orders.customer_numb, 
    sum(order_lines.cost_line) as sum_cost_line, 
. . .
ORDER BY sum_cost_line

注:一部のRDBMSは、明示的に指定されていなくても、グループ化のための追加の式を意味すると聞いています。OracleはそれらのRDBMSの1つではありません。

両方によるグループ化については、2人の顧客がいるDBcustomer_numbcost_line考えてみましょう。1と2は、それぞれ1行ずつ2つの注文があります。

Customer Number | Cost Line
              1 |     20.00
              1 |     20.00
              2 |     35.00
              2 |     30.00

 select customer_number, cost_line, sum(cost_line)
 FROM ...
 group by customer_number, cost_line
 order by sum(cost_line) desc

Customer Number | Cost Line | sum(cost_line)
              1 |     20.00 |          40.00
              2 |     35.00 |          35.00
              2 |     30.00 |          30.00

最も高い最初の行sum(cost_line)は、最も多くを費やした顧客ではありません。

于 2012-10-23T04:47:18.177 に答える
3

結合がどのように機能するかを理解していますが、customer_numbとcost_line(sum()を使用して支出額を計算する)を単純にGROUPBYできない理由を理解できないようです。

これにより、すべての顧客の合計が得られるはずです。

SELECT orders.customer_numb, sum(order_lines.cost_line)
FROM orders
INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
GROUP BY orders.customer_numb

集計関数の引数ではないSELECT句のすべての列は、GROUPBY句の列でもあることに注意してください。

これで、他のテーブルと結合して詳細を取得できます。一般的なテーブル式を使用する1つの方法を次に示します。(あなたが望むものを表現する他の方法があります。)

with customer_sums as (
    -- We give the columns useful aliases here.
    SELECT orders.customer_numb as customer_numb, 
           sum(order_lines.cost_line) as total_orders
    FROM orders
    INNER JOIN order_lines ON order_lines.order_numb = orders.order_numb
    GROUP BY orders.customer_numb
)
select c.customer_numb, c.customer_first_name, c.customer_last_name, cs.total_orders
from customers c
inner join customer_sums cs
on cs.customer_numb = c.customer_numb
order by cs.total_orders desc

GROUPBYorders.cost_lineだけを使用してデータをcost_lineでグループ化できないのはなぜですか。

GROUP BYをorder_lines.cost_lineに適用すると、order_lines.cost_lineの個別の値ごとに1つの行が得られます。(列orders.cost_lineは存在しません。)そのデータは次のようになります。

OL.ORDER_NUMB OL.COST_LINE O.CUSTOMER_NUMB C.CUSTOMER_FIRST_NAME C.CUSTOMER_LAST_NAME
--
1             1.45         2014            Julio                 Savell
1             2.33         2014            Julio                 Savell
1             1.45         2014            Julio                 Savell
2             1.45         2014            Julio                 Savell
2             1.45         2014            Julio                 Savell
3             13.00        2014            Julio                 Savell

order_lines.cost_lineでグループ化できますが、有用な情報は提供されません。このクエリ

select order_lines.cost_line, orders.customer_numb
from order_lines
inner join orders on orders.customer_numb = order_lines.customer_numb
group by order_lines.cost_line;

このようなものを返す必要があります。

OL.COST_LINE O.CUSTOMER_NUMB 
--
1.45         2014
2.33         2014
13.00        2014

ひどく役に立たない。

注文明細の合計に関心がある場合は、グループ化(要約)する1つまたは複数の列を決定する必要があります。注文番号でグループ化(要約)すると、3行になります。顧客番号でグループ化(要約)すると、1行になります。

于 2012-10-23T02:46:04.200 に答える