4

Postgres でこのコードに問題があります。ユーザーテーブルのすべてのフィールドを取得したいのですが、ID でのみグループ化します。これは MySQL と SQLite でうまく機能しますが、グーグルで調べたところ、この動作は標準の一部ではないことがわかりました。

SELECT u.*, p.*, count(o.id) AS order_count
FROM shop_order AS o
LEFT JOIN user AS u ON o.user_id = u.id
LEFT JOIN userprofile AS p ON p.user_id = u.id
WHERE o.shop_id = <shop_id>
GROUP BY u.id

<shop_id>(はプログラムで渡されるので、任意の整数に簡単に置き換えることができることに注意してください。)

これは私が得ているエラーです

column "u.id" must appear in the GROUP BY clause or be used in an aggregate function

私はSQLの初心者なので、これが明らかな場合は優しくしてください:)

4

5 に答える 5

4

user残念ながら、とのすべての列をリストしないと、それはできないと思いますuserprofile。(ワイルドカードの使用は、単純なアドホック クエリに対してのみ行うものと見なされることがよくあります。これが理由の 1 つだと思います!) BY 句でも集計関数でも、各グループのその列の値のいずれかを結果に表示できます。PostgreSQL は少し厳密です。

ただし、通常、テーブルの数列だけでグループ化に十分です。書き直す方法はいくらでもあります。おそらく、代わりにできることは次のとおりです。

SELECT u.*, p.*, (select count(o.id) FROM shop_order AS o WHERE o.user_id = u.id AND o.shop_id = <shop_id>) AS order_count
FROM user AS u
LEFT JOIN userprofile AS p ON p.user_id = u.id    
于 2012-04-16T07:44:36.663 に答える
2

データベースに特定性の低いものをカウントするように依頼しようとしている 注文をカウントしたいが、すべての詳細を表示したい場合、ユーザープロファイルにユーザーごとに複数の行が含まれていて、それらの行が異なる場合はどうなるでしょうか?各 u.id に対して複数の行を取得し、1 つだけが必要であると指定したため、データベースは「離れて、本当に欲しいものを教えてください」と言っています。

于 2012-04-16T07:55:43.207 に答える
2

Postgres のバージョンは?Postgres 9.0 以前を使用している場合、コード構成は実行されません。たとえば、これは許可されていません:

SELECT
    p.id,
    p.firstname, p.lastname, p.address, -- these auxiliary fields is helpful to program users
    count(*)
FROM
    people p
    JOIN visits v ON p.id = v.person_id
GROUP BY p.id

9.0 以下でこれを行う必要があります。

SELECT
    p.id,
    p.firstname, p.lastname, p.address, -- these auxiliary fields is helpful to program users
    count(*)
FROM
    people p
    JOIN visits v ON p.id = v.person_id
GROUP BY p.id
    ,p.firstname, p.lastname, p.address; -- these ancillary fields aids the RDBMS on preventing
    -- programmers from accidentally committing the same mistake as MySQL programmers.

Postgres 9.1 を使用している場合、GROUP BY フィールドが主キーである限り、SELECT 句に多くのフィールドがあっても、GROUP BY で使用できるフィールドは 1 つだけです。したがって、これは実行されます:

SELECT
    p.id,
    p.firstname, p.lastname, p.address, -- these auxiliary fields is helpful to program users
    count(*)
FROM
    people p
    JOIN visits v ON p.id = v.person_id
GROUP BY p.id 
-- note that there's no need to repeat the SELECTed fields on GROUP BY clause

Postgres 9.1 は、主キーへの機能依存性を容易にすることができるため、GROUP BY 句に主キーのみを含めることが許可されています。

SQL フィドルの例: http://sqlfiddle.com/#!1/3b857/3

于 2012-04-16T07:58:54.080 に答える
2

row_number結果をユーザーごとに 1 行に制限するために使用できます。

select  *
from    (
        select  row_number() over (partition by u.id) as rn
        ,       *
        join    user u
        on      sub.user_id = u.id
        join    shop_order so
        on      so.user_id = u.id
        left join
                userprofile up
        on      up.user_id = u.id
        where   so.shop_id = <shop_id>
        ) as SubQueryAlias
where   rn = 1

row_numberPostgresではwhere句のようなウィンドウ関数が許可されていないため、サブクエリが必要です。

于 2012-04-16T07:44:13.127 に答える
2

使用している PostgreSQL のバージョンは? 9.1より前のものだと思います。

バージョン 9.1 以降GROUP BYの PostgreSQL は、主キー列を作成する場合に必要な機能もサポートしています。したがって、ここではアップグレードが良いオプションかもしれません。

于 2012-04-16T08:10:53.483 に答える