テーブルからデータを選択する機能があります。選択したデータとそのテーブルの行の総数を返したいのですが。
どうすればそれを行うことができますか、または最も効率的な方法で同じ結果を得るにはどうすればよいですか?
私はいくつかのことを試しましたが、以下のコードで終わりました、これは私が望む形式ですが、count(*) over () as total_count
は常に1を返します。返すために必要なのは行の総数ですそのrecords
から選択します。
SELECT
row_to_json(selected_records) as data
FROM
(
SELECT
count(*) over () as total_count,
array_to_json(array_agg(row_to_json(records))) as data
FROM (
SELECT
sum(entrances) as entrances
FROM report_la
WHERE profile_id = 3777614
GROUP BY landing_path_id
limit 10 offset 0
) records
) as selected_records
更新されました、以下のコードは私が望む結果を生み出しています、それを隠すことができればいいですtotal_count
records
選択からの列
SELECT
row_to_json(selected_records) as data
FROM
(
SELECT
min(total_count) as total_count
,array_to_json(array_agg(row_to_json(records))) as data
FROM (
SELECT
sum(entrances) as entrances
,count(*) over () as total_count
FROM ga.report_la
WHERE ga_profile_id = 3777614
GROUP BY landing_path_id
limit 10
) records
) as selected_records
質問を理解しているので、ウィンドウ関数は必要ありません。集約関数がその役割を果たします。
count()
(-> _row_ct
_)。sum()
次のレベルの結果の_row_ct
_(-> _total_row_ct
_)。_SELECT row_to_json(selected_records)::text AS data
FROM (
SELECT array_to_json(array_agg(row_to_json(records))) AS data
, sum(row_ct) AS total_row_ct
FROM (
SELECT landing_path_id
, sum(entrances) AS entrances
, count(*) AS row_ct
FROM report_la
WHERE profile_id = 3777614
GROUP BY landing_path_id
LIMIT 10
) records
) selected_records;
_
_landing_path_id
_も含めたので、結果のデータは意味があります。
集計されていない行がないため、ウィンドウ関数(count(*) over ()
)は期待どおりではないようです。
あなたが内部サブクエリに追加できます:
_count(*) OVER ()
_
..興味深い__landing_path_id
_のカウントを取得する。しかし、それは「そのレコードが選択したレコードの合計行数」が意図したものではないようです。
または、あなたが内部サブクエリに追加できます:
_sum(count(*)) OVER ()
_
..すべての_landing_path_id
_の合計数を冗長に取得しますが、それは無意味に思えます。これを説明するために、単一パスで集計関数の結果に対してウィンドウ関数を実行することは可能であることを述べました。その詳細:
records
サブクエリに_total_count
_を含まない結果。内側のLIMIT
のSELECT
を考慮に入れます。最大10個の異なる_landing_path_id
_が選択されている場合でも、all修飾_landing_path_id
_がカウントされます。
1回のスキャンで両方を取得し、カウントを再利用して個別に合計するには、[〜#〜] cte [〜#〜]を導入します。
_WITH cte AS (
SELECT sum(entrances) AS entrances
, count(*) over () AS total_count
FROM report_la
WHERE profile_id = 3777614
GROUP BY landing_path_id
LIMIT 10
)
SELECT row_to_json(selected_records)::text AS data
FROM (
SELECT (SELECT total_count FROM cte LIMIT 1) AS total_count
, array_to_json(array_agg(row_to_json(records))) AS data
FROM (SELECT entrances FROM cte) records
) selected_records;
_
属性名を気にしない場合は、サブクエリを使用してcheaperにすることができます。
_SELECT row_to_json(selected_records)::text AS data
FROM (
SELECT min(total_count) AS total_count
, array_to_json(array_agg(row_to_json(ROW(entrances)))) AS data
FROM (
SELECT sum(entrances) AS entrances
, count(*) over () AS total_count -- shouldn't show up in result
FROM report_la
WHERE profile_id = 3777614
GROUP BY landing_path_id
LIMIT 1
) records
) selected_records;
_
entrances
式は列名を保持しないため、ROW
ではなくデフォルトの属性名_f1
_を取得します。
特定の属性名が必要な場合、行を登録済みの型にキャストできます。 (Ab-)_TEMP TABLE
_を使用して、セッションの行タイプを登録します。
_CREATE TEMP TABLE rec1 (entrances bigint);
...
, array_to_json(array_agg(row_to_json(ROW(entrances)::rec1))) AS data
...
_
これは、CTEよりも少し高速です。または、より詳細ですがキャストなし:
_...
, array_to_json(array_agg(row_to_json(
(SELECT x FROM (SELECT records.entrances) x)))) AS data
...
_
この関連する回答の詳細な説明:
あなたはa_horse_with_no_nameまたはForguesRが提案したことを実行できます(私はa_horse_with_no_nameの提案がForguesRよりも効率的だと思います)。しかし、これらは結果セットに追加の列を提供します。それは、その追加の列が必要かどうか(すべて同じデータが繰り返されることを示す)か、「要約行」のような結果セット内の行が必要かどうかに依存します。
「要約行」タイプの結果に関心がある場合は、私の回答で対処します。
別のオプションは、探しているCOUNT(*)
を提供するクエリを作成し、元のクエリでそれをUNION
することです。もちろん、これの秘訣は、両方のクエリに同じ数の列があり、COUNT(*)
クエリが最後になることを確認することです。そのために、並べ替えに使用する列を追加しました。以下の簡単な例を参照してください。
-- assume col1, col2 are VARCHAR and col3, col4 are NUMERIC
SELECT
col1, col2, col3, col4
FROM (
SELECT
col1, col2, col3, col4, 1 AS sorter
FROM tab1
UNION
SELECT
NULL::VARCHAR AS col1, NULL::VARCHAR AS col2, NULL::NUMERIC AS col3, COUNT(*) AS col4, 2 AS sorter
FROM tab1
) a
ORDER BY a.sorter, a.col1, a.col2;
テーブルのすべての行の数を取得するには、サブクエリを含めるだけです。何かのようなもの :
SELECT *, (SELECT COUNT(*) FROM yourTable) AS TotalNbRows FROM yourTable
集計クエリをサブクエリに入れます
SELECT COUNT( * )
FROM (
SELECT COUNT( * ) AS `count`
FROM lms
WHERE `lead_school_type` =3
AND subscription.vad =1
GROUP BY lms.user_id
) AS subcount