2017-05-01 13 views
6

Tôi đang cố gắng để thực hiện nhiều truy vấn trên một bảng duy nhất sử dụng một quy tắc UNIONCouldnt xác định hành bình đẳng kiểu json [] khi dùng UNION

Tôi có hai bảng:

  • dự án (id, tên, BOOLEAN pinned)
  • kỹ năng (M2M cho các dự án)

tôi đang tìm đến đầu tiên nhận được một loạt các hàng có pinned thiết lập để true và lấp đầy còn lại với các mục mới nhất (pinned thiết lập để false)

SELECT 
    project.id AS project_id, 
    project.name AS project_name, 
    array_agg(json_build_object('skill_id', project_skills.id,'name', project_skills.skill)) AS skills 
from project 
LEFT OUTER JOIN project_skills on project.name = project_skills.project 
WHERE project.pinned = true 
GROUP BY project_id,project_name 

UNION 

SELECT 
    project.id AS project_id, 
    project.name AS project_name, 
    array_agg(json_build_object('skill_id', project_skills.id,'name', project_skills.skill)) AS skills 
from project 
LEFT OUTER JOIN project_skills on project.name = project_skills.project 
WHERE project.id != 1 AND project.pinned = false 
GROUP BY project_id,project_name 
ORDER BY project.create_date DESC LIMIT 5 

Khi thực hiện truy vấn này, tôi nhận được báo lỗi dưới đây

ERROR: could not identify an equality operator for type json[] 
LINE 7: array_agg(json_build_object('skill_id', project_skills.id,... 

Tôi không hiểu điều này lỗi. Có phải vì nó đang cố gắng so sánh các cột json từ cả hai kết quả?

Tôi đang sử dụng Postgres 9.4.

Trả lời

8

Khi bạn sử dụng UNION, DBMS loại bỏ mọi hàng trùng lặp và để làm như vậy, cần xác định xem hai hàng có giống nhau hay không. Điều này có nghĩa là nhìn vào từng cột của hai hàng mà nó so sánh và quyết định xem chúng có bằng nhau không.

Thông báo lỗi bạn thấy là nơi một trong các cột của bạn được tạo bằng cách sử dụng array_agg(json_build_object(...)) tạo ra giá trị loại json[], có nghĩa là "mảng giá trị json". Bởi vì Postgres không biết làm thế nào để so sánh hai mảng giá trị JSON, nên nó không thể quyết định nếu UNION các bản sao được tạo ra của bạn.

Nếu bạn không thực sự quan tâm đến việc xóa các mục trùng lặp, giải pháp đơn giản nhất là sử dụng UNION ALL bỏ qua bước này.

+4

@Kunkka: Nếu 'UNION' là * cần thiết * một cách khác là chuyển sang' jsonb' (hoặc đưa mảng vào 'jsonb []' tương ứng), toán tử bình đẳng được xác định. Xem: http://stackoverflow.com/a/24296054/939860 hoặc http://stackoverflow.com/a/30520760/939860. (Bạn mất định dạng ban đầu, mặc dù - thường không liên quan.) –

+0

Có cùng vấn đề và tôi chỉ truyền giá trị vào văn bản bằng cách sử dụng ':: text' cả trong nhóm và trong lựa chọn để tạo điều kiện so sánh nó bị khiếu nại. Đã được xây dựng hệ thống phân cấp của quan điểm để ở một cấp độ lên, tôi chỉ cần quay trở lại json khi cần thiết với ':: json []'. Sử dụng Pg 9.6. –

1

Hóa ra tất cả những gì tôi phải làm là sử dụng UNION ALL - tôi đoán điều này bỏ qua việc cố gắng so sánh các loại json trên các truy vấn.

+0

Đây phải là nhận xét cho câu trả lời của IMSoP. –

+0

@ErwinBrandstetter tôi thực sự đã tìm ra giải pháp trước khi tôi có thể nhận được câu trả lời cho bài đăng này. tôi chỉ cần thêm câu trả lời của tôi thay vì xóa bài đăng. Tôi chấp nhận câu trả lời của mình dù rằng nó hữu ích hơn tôi – Kannaj

Các vấn đề liên quan