PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Sử dụng UNNEST với một JOIN

Về mặt kỹ thuật, truy vấn của bạn có thể hoạt động như thế này (không hoàn toàn chắc chắn về mục tiêu của truy vấn này):

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;

Tuy nhiên, với tôi, có vẻ như bạn đang đi sai hướng ở đây. Thông thường người ta sẽ loại bỏ mảng dư thừa taglist và giữ lược đồ cơ sở dữ liệu chuẩn hóa. Sau đó, truy vấn ban đầu của bạn sẽ phân phát tốt, chỉ được rút ngắn cú pháp với bí danh:

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;

Làm sáng tỏ bí ẩn

<rant> Nguyên nhân sâu xa dẫn đến "các kết quả khác nhau" của bạn là do quy ước đặt tên không may mà một số ORM thách thức trí tuệ áp đặt lên mọi người.
Tôi đang nói về id như tên cột. Không bao giờ sử dụng mẫu chống này trong cơ sở dữ liệu có nhiều hơn một bảng. Đúng, về cơ bản có nghĩa là bất kỳ cơ sở dữ liệu. Ngay sau khi bạn tham gia nhiều bảng (đó là những gì bạn làm trong cơ sở dữ liệu) bạn kết thúc với một loạt các cột có tên id . Hoàn toàn vô nghĩa.
Cột ID của bảng có tên là thẻ tag phải là tag_id (trừ khi có tên mô tả khác). Không bao giờ id . </rant>

Truy vấn của bạn vô tình đếm các thẻ tag thay vì 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;

Nó sẽ hoạt động theo cách này:

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;

Tôi cũng đã thêm lại DISTINCT vào count() của bạn đã bị mất trong suốt quá trình truy vấn của bạn.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách nhận kết quả postgresql_query từ Ansible

  2. Cách cài đặt Gnatcoll Postgres trên Linux Centos 7

  3. SQL lấy tên những người không làm việc trong một dự án

  4. Định nghĩa của sub-index trong postgresql là gì?

  5. Cách điền vào các hàng dựa trên dữ liệu loại sự kiện