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

Xoay vòng trên nhiều cột bằng cách sử dụng Tablefunc

Vấn đề với truy vấn của bạn là b c chia sẻ cùng một dấu thời gian 2012-01-02 00:00:00 và bạn có timestamp cột timeof đầu tiên trong truy vấn của bạn, vì vậy - mặc dù bạn đã thêm dấu nhấn đậm - bc chỉ là các cột bổ sung nằm trong cùng một nhóm 2012-01-02 00:00:00 . Chỉ cái đầu tiên (b ) được trả về kể từ khi (trích dẫn sách hướng dẫn):

row_name cột phải ở vị trí đầu tiên. Danh mục category và giá trị category cột phải là hai cột cuối cùng, theo thứ tự đó. Bất kỳ cột nào giữa row_namecategory được coi là "phụ". Các cột "bổ sung" dự kiến ​​sẽ giống nhau cho tất cả các hàng có cùng row_name giá trị.

Tôi nhấn mạnh đậm.
Chỉ cần hoàn nguyên thứ tự của hai cột đầu tiên để tạo entity tên hàng và nó hoạt động như mong muốn:

SELECT * FROM crosstab(
      'SELECT entity, timeof, status, ct
       FROM   t4
       ORDER  BY 1'
      ,'VALUES (1), (0)')
 AS ct (
    "Attribute" character
   ,"Section" timestamp
   ,"status_1" int
   ,"status_0" int);

entity tất nhiên phải là duy nhất.

Nhắc lại

  • row_name đầu tiên
  • (tùy chọn) extra cột tiếp theo
  • category (như được xác định bởi tham số thứ hai) và giá trị category cuối cùng .

Các cột bổ sung được điền từ đầu tiên hàng từ mỗi row_name vách ngăn. Giá trị từ các hàng khác bị bỏ qua, chỉ có một cột cho mỗi row_name để điền vào. Thông thường, những điều này sẽ giống nhau cho mọi hàng của một row_name , nhưng điều đó tùy thuộc vào bạn.

Để biết cách thiết lập khác trong câu trả lời của bạn:

SELECT localt, entity
     , msrmnt01, msrmnt02, msrmnt03, msrmnt04, msrmnt05  -- , more?
FROM   crosstab(
        'SELECT dense_rank() OVER (ORDER BY localt, entity)::int AS row_name
              , localt, entity -- additional columns
              , msrmnt, val
         FROM   test
         -- WHERE  ???   -- instead of LIMIT at the end
         ORDER  BY localt, entity, msrmnt
         -- LIMIT ???'   -- instead of LIMIT at the end
     , $$SELECT generate_series(1,5)$$)  -- more?
     AS ct (row_name int, localt timestamp, entity int
          , msrmnt01 float8, msrmnt02 float8, msrmnt03 float8, msrmnt04 float8, msrmnt05 float8 -- , more?
            )
LIMIT 1000  -- ??!!

Không có gì ngạc nhiên khi các truy vấn trong bài kiểm tra của bạn hoạt động đáng kinh ngạc. Thiết lập thử nghiệm của bạn có 14 triệu hàng và bạn xử lý tất cả trong số chúng trước khi vứt bỏ hầu hết với LIMIT 1000 . Để có tập hợp kết quả giảm, hãy thêm điều kiện WHERE hoặc LIMIT vào truy vấn nguồn!

Thêm vào đó, mảng bạn làm việc không cần thiết phải tốn kém. Thay vào đó, tôi tạo một tên hàng thay thế bằng bold_rank ().

db <> fiddle tại đây - với thiết lập thử nghiệm đơn giản hơn và ít hàng hơ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ác hàng trùng lặp trong một bảng khóa chính.

  2. Giới hạn quyền truy cập của người dùng PostgreSQL bằng lược đồ và chế độ xem

  3. Sử dụng địa chỉ email làm khóa chính?

  4. 3 cách liệt kê tất cả các hàm trong PostgreSQL

  5. pg_dump cơ sở dữ liệu postgres từ máy chủ từ xa khi cổng 5432 bị chặn