sql >> データベース >  >> RDS >> PostgreSQL

JOINでUNNESTを使用する

    技術的には、クエリは次のように機能する可能性があります(このクエリの目的については完全にはわかりません):

    SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
    FROM  (
        SELECT  unnest(m.taglist) AS tag_id
        FROM    mentions m
        WHERE   m.search_id = 3
        AND     9 = ANY (m.taglist)
        ) m 
    JOIN   tags t  USING (tag_id) -- assumes tag.tag_id!
    GROUP  BY t.parent_id;
    

    しかし、あなたはここで間違った方向に進んでいるように私には思えます。通常、冗長配列taglistを削除します 正規化されたデータベーススキーマを保持します。そうすれば、元のクエリはうまく機能するはずですが、エイリアスを使用して構文を短縮するだけです:

    SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
    FROM   mentions m
    JOIN   taggings mt ON mt.mention_id = m.id
    JOIN   tags     t  ON t.id = mt.tag_id
    WHERE  9 = ANY (m.taglist)
    AND    m.search_id = 3
    GROUP  BY t.parent_id;
    

    謎を解き明かす

    <rant> 「異なる結果」の根本的な原因は、一部の知的に挑戦されたORMの不幸な命名規則です。 人々に課す。
    私はid 列名として。複数のテーブルがあるデータベースでは、このアンチパターンを使用しないでください。そうです、それは基本的に任意を意味します データベース。たくさんのテーブルに参加するとすぐに(それが データベース内)idという名前の列の束になります 。まったく意味がありません。
    tagという名前のテーブルのID列 tag_idである必要があります (別の説明的な名前がない限り)。 idは絶対にしないでください 。</rant>

    クエリが誤ってtagsをカウントします mentionsの代わりに :

    SELECT 25 AS keyword_id, count(m.id) AS total, t.parent_id AS tag_id
    FROM  (
        SELECT unnest(m.taglist) AS id
        FROM   mentions m
        WHERE  m.search_id = 4
        AND    25 = ANY (m.taglist)
        ) m
    JOIN   tags t USING (id)
    GROUP  BY t.parent_id;
    

    このように機能するはずです:

    SELECT 25 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id
    FROM  (
        SELECT m.id, unnest(m.taglist) AS tag_id
        FROM   mentions m
        WHERE  m.search_id = 4
        AND    25 = ANY (m.taglist)
        ) m
    JOIN   tags t ON t.id =  m.tag_id
    GROUP  BY t.parent_id;

    DISTINCTも追加し直しました count()に クエリの途中で失われました。



    1. Node.js:SequelizeでのPostgresスキーマの定義

    2. EclipseHibernate.cfg.xmlはMySQLからsysデータベースをリンクしています

    3. SQL、参加に関する質問

    4. MYSQLは各カテゴリからランダムに選択します