Postgresql 将数组转换为对象

问题描述 投票:0回答:1

我正在尝试使用以下查询在 PostgreSQL 中构建函数。我已经得到了预期的

where
条件行为,但问题是我需要将某些列作为对象而不是数组返回。
shipper
buyer
seller
是我想作为对象而不是数组返回的列。帮助我应该编辑查询的哪一部分。

这是我的询问

BEGIN
  RETURN 
  
    (select 
  json_agg(orders)
    from 
  (
    select 
      orders.id, 
      orders.invoice_number, 
      orders.order_status, 
      orders.line_items,
      orders.total_product_amount, 
      orders.total_amount, 
      orders.confirm_expiry, 
      orders.shipping_expiry, 
      orders.completion_expiry,
      orders.cancellation_reason, 
      orders.cancellation_approval_expiry, 
      orders.cancellation_description,
(
  select 
        json_agg(json_build_object(
          'id', order_shippings.id, 
          'provider', order_shippings.provider,
          'service_name', order_shippings.service_name,
          'destination_address', order_shippings.destination_address,
          'destination_receiver_name', order_shippings.destination_receiver_name,
          'destination_phone_number', order_shippings.destination_phone_number,
          'destination_address_label', order_shippings.destination_address_label,
          'estimated_delivery', order_shippings.estimated_delivery,
          'shipping_cost', order_shippings.shipping_cost,
          'weight', order_shippings.weight,
          'partner_booking_id', order_shippings.partner_booking_id,
          'awb', order_shippings.awb,
          'proof_of_delivery', order_shippings.proof_of_delivery,
          'tracking_url', order_shippings.tracking_url))
          from 
            order_shippings
          where
            order_shippings.order_id = orders.id
      ) as shipping, 
      (
        select 
          json_agg(json_build_object(
            'id', profiles.id, 
            'toco_name', profiles.toco_name, 
            'toco_profile_picture', profiles.toco_profile_picture))
        from 
          profiles 
        where 
          profiles.id = orders.store_id
      ) as seller, 
      (
        select 
          json_agg(json_build_object(
            'id', profiles.id, 
            'display_name', profiles.display_name, 
            'is_online', profiles.is_online, 
            'profile_picture', profiles.profile_picture))
        from 
          profiles 
        where 
          profiles.id = orders.buyer_id
      ) as buyer
    from 
      public.orders 
      left join profiles s on s.id = orders.store_id 
      left join profiles b on b.id = orders.buyer_id 
      left join order_shippings on order_shippings.order_id = orders.id
    where 
      orders.store_id = store_id_params
      and case when keyword is not null and keyword <> '' then (
        orders.invoice_number ilike concat('%', keyword, '%') 
        or s.toco_name ilike concat('%', keyword, '%') 
        or b.display_name ilike concat('%', keyword, '%')
        or exists (
            select 1
            from jsonb_array_elements(orders.line_items) AS item
            where item->'listing'->>'title' ilike concat('%', keyword, '%')
          )
      ) else true end
      and case when range_start is not null and range_start <> '' then (
        orders.created_at >= to_timestamp(
          range_start, 'yyyy-MM-ddTHH:mi:ssZ'
        ) 
        and orders.created_at <= to_timestamp(
          range_end, 'yyyy-MM-ddTHH:mi:ssZ'
        )
      ) else true end
      and case 
          when order_status_type = 'all' then (
            orders.order_status not in(100,103)
          )
          when order_status_type = 'cancelled' then (
            (orders.order_status >= 0 and orders.order_status <= 100) or orders.order_status = 430 
          )
          when order_status_type = 'new' then (
            orders.order_status in(220, 221) 
          )
          when order_status_type = 'not_sent' then (
            orders.order_status in(400, 410, 450)
          )   
          when order_status_type = 'on_delivery' then (
            orders.order_status >= 500 and orders.order_status <= 600
          )
          when order_status_type = 'finished' then (
            orders.order_status in(601, 700, 702, 800)
          )
          when order_status_type = 'complained' then (
            orders.order_status in(690, 701)
          )
          else true end
    order by 
      (case when sort = 0 then orders.created_at end) desc,
      (case when sort = 1 then orders.created_at end) asc, 
      (case when sort = 2 then orders.total_amount end) desc,
      (case when sort = 3 then orders.total_amount end) asc
    limit 
      size offset pos
  ) as orders);
END;

像这样运行

select * from order_list_seller(10, 0, 1, 'FLORAL', null, null, 'all', '3ab1222c-b8cb-4259-9c28-cfd4db84e70b');

这是我收到的

[
{
    "id": "82b1f561-6c9f-4471-919b-e33ec5a6ee54",
    "invoice_number": "INV/21032024/TEC/00000803",
    "order_status": 701,
    "line_items": [
      {
        "id": "55234bb8-d8f0-4e49-bc8e-156167967f1c",
        "store": {
          "id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
          "email": "[email protected]",
          "phone": null,
          "gender": "male",
          "birthday": "1920-01-18",
          "provider": "google",
          "username": "[email protected]",
          "fcm_token": null,
          "is_online": false,
          "toco_city": "Kabupaten Tangerang",
          "toco_name": "Rushman store",
          "created_at": "2024-02-19T09:58:22.121474+00:00",
          "deleted_at": null,
          "toco_phone": "0894949597898",
          "updated_at": "2024-03-20T10:14:02.877189+00:00",
          "profile_kyc": "COMPLETED",
          "display_name": "QA TAD01",
          "toco_address": "Jalan Kampung Tegal, Pagedangan, Pagedangan, Kabupaten Tangerang, Banten",
          "toco_village": "Pagedangan",
          "deleted_email": null,
          "deleted_phone": null,
          "latest_online": "2024-03-20T07:27:08.479458+00:00",
          "toco_district": "Pagedangan",
          "toco_latitude": -6.2942883,
          "toco_province": "Banten",
          "toco_logistics": [
            "0376bc47-0053-459a-b45b-7b0d5114054f",
            "db244b57-1f4d-40b9-afc7-61b97be2a7b3",
            "e6eb1317-f63f-49b9-b6d7-39b63d9870bc",
            "619dc301-28d3-40f8-921e-43d5ad7cfd91",
            "52820f0b-f7c2-40d8-9a52-88d179c9f3bd"
          ],
          "toco_longitude": 106.6378479,
          "profile_picture": "https://lh3.googleusercontent.com/a/ACg8ocLPbK3cDazSOU-a2melZXz28tJnt3_FNpJ9Ex3eqjU8LYs=s96-c",
          "toco_created_at": "2024-02-19T10:01:55.161945+00:00",
          "toco_short_name": "rasman-music-store",
          "tnc_confirmed_at": "2024-02-19T16:58:30.394704+00:00",
          "toco_description": "Gua jual lo beli.",
          "toco_postal_code": 15339,
          "email_confirmed_at": "2024-02-19T09:58:22.141892+00:00",
          "phone_confirmed_at": null,
          "toco_district_code": "36.03.22",
          "toco_banner_picture": "https://toco-img.azureedge.net/static/store_banner/[email protected]",
          "email_confirmed_sent": null,
          "toco_profile_picture": "https://toco-img.azureedge.net/toco/afc4853d-191a-4b48-9255-e711361cf61e-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-hl_image_picker_BOcNuxxim7.jpg",
          "toco_location_description": "Jalan menuju surga"
        },
        "listing": {
          "id": "62d46d17-6935-4ee5-b121-7884172e48b9",
          "lat": -6.2942883,
          "lng": 106.6378479,
          "new": true,
          "sku": "34234234234234234234",
          "city": "Kabupaten Tangerang",
          "fuel": null,
          "slug": "brand-logo-floral-hoodie",
          "sold": 0,
          "type": "177ca046-0278-46d3-9f24-b83e9798a48f",
          "color": null,
          "kudos": null,
          "likes": null,
          "price": 1400000,
          "stock": 1,
          "store": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
          "title": "BRAND LOGO FLORAL HOODIE",
          "views": 7,
          "width": 0,
          "height": 0,
          "length": 0,
          "photos": [
            "https://toco-img.azureedge.net/toco/100f53a9-155d-43cd-a8cc-145bedcca962-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-image_listing_1709745963292.jpg"
          ],
          "weight": 500,
          "deleted": false,
          "mileage": null,
          "archived": false,
          "bold_end": null,
          "category": "af11c431-1020-4dbd-8983-929f61afa784",
          "lot_area": null,
          "sub_type": null,
          "verified": true,
          "min_order": 1,
          "promo_end": null,
          "created_at": "2024-03-06T17:26:05.747263+00:00",
          "created_by": null,
          "daytop_end": null,
          "department": {
            "id": "9cd2e21c-a0d3-4b2a-b86e-d16d46190c96",
            "icon": "https://toco-img.azureedge.net/static/category_icon_7_11_2023/Main%20Category=Olahraga.png",
            "slug": "olahraga",
            "sort": 10,
            "image": null,
            "mobile": "https://toco-img.azureedge.net/static/Toco%20Category%20Banner%20Mobile/Olahraga.jpg",
            "desktop": "https://toco-img.azureedge.net/static/Toco%20Category%20Banner%20Web/Olahraga.jpg",
            "name_en": "Olahraga",
            "name_id": "Olahraga",
            "homepage": true,
            "classified": null,
            "created_at": "2023-07-14T08:43:46.437967+00:00",
            "updated_at": "2023-07-14T08:43:46.437967+00:00",
            "recommended": false,
            "joi_category": null,
            "sort_desktop": 6,
            "darkmode_icon": null,
            "sort_desktop_classified": null
          },
          "facilities": null,
          "tax_expiry": null,
          "thumbnails": [
            "https://toco-img.azureedge.net/toco/100f53a9-155d-43cd-a8cc-145bedcca962-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-image_listing_1709745963292-thumbnail.jpg"
          ],
          "updated_at": "2024-03-18T06:51:07.311066+00:00",
          "updated_by": null,
          "add_to_cart": true,
          "choosen_end": null,
          "description": "Art by Mike Gigliotti\n10 oz 70% Cotton/30% Polyester",
          "rental_type": null,
          "bedroom_area": null,
          "special_bold": null,
          "building_area": null,
          "building_name": null,
          "price_special": null,
          "rental_period": null,
          "special_promo": null,
          "number_of_seat": null,
          "special_daytop": null,
          "number_of_floor": null,
          "production_year": null,
          "special_choosen": null,
          "suggestion_descr": "SKU terlalu panjang",
          "cylinder_capacity": null,
          "legal_certificate": null,
          "number_of_bedroom": null,
          "sub_type_category": null,
          "suggestion_photos": null,
          "transmission_type": null,
          "number_of_bathroom": null,
          "additional_equipment": null,
          "license_plate_category": null
        },
        "user_id": "963a3e3b-fdfd-47ac-9efe-f03ea0b2f1b4",
        "quantity": 1,
        "store_id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
        "created_at": "2024-03-21T03:03:18.862256+00:00",
        "listing_id": "62d46d17-6935-4ee5-b121-7884172e48b9",
        "updated_at": null
      }
    ],
    "total_product_amount": 1400000,
    "total_amount": 1410000,
    "confirm_expiry": "2024-03-22T03:03:50.774+00:00",
    "shipping_expiry": null,
    "completion_expiry": null,
    "cancellation_reason": null,
    "cancellation_approval_expiry": null,
    "cancellation_description": null,
    "shipping": [
      {
        "id": "8e8b5327-16eb-4c34-9899-990e4580005a",
        "provider": "jne",
        "service_name": "JNE REG",
        "destination_address": "Kost Putri Kosmologi Studento L10/9 BSD, Pagedangan, Kecamatan Pagedangan, Kabupaten Tangerang, Banten",
        "destination_receiver_name": "Hani",
        "destination_phone_number": "082190784194",
        "destination_address_label": "Kost",
        "estimated_delivery": "23 Mar - 24 Mar",
        "shipping_cost": 10000,
        "weight": 1000,
        "partner_booking_id": null,
        "awb": null,
        "proof_of_delivery": null,
        "tracking_url": null
      }
    ],
    "seller": [
      {
        "id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
        "toco_name": "Rushman store",
        "toco_profile_picture": "https://toco-img.azureedge.net/toco/afc4853d-191a-4b48-9255-e711361cf61e-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-hl_image_picker_BOcNuxxim7.jpg"
      }
    ],
    "buyer": [
      {
        "id": "963a3e3b-fdfd-47ac-9efe-f03ea0b2f1b4",
        "display_name": "Hani Hani Dwi ",
        "is_online": false,
        "profile_picture": "https://toco-img.azureedge.net/toco/7fba2ee3-c53c-443a-9cad-f60e79e43bbd-963a3e3b-fdfd-47ac-9efe-f03ea0b2f1b4-CROP_20240313111442802.jpg"
      }
    ]
  },
  {
    "id": "b27b3701-6f37-4f8f-92da-c08c88ca4016",
    "invoice_number": "INV/21032024/TEC/00000805",
    "order_status": 7,
    "line_items": [
      {
        "id": "2554bd60-0088-43a5-bcca-6ce55bb26a59",
        "store": {
          "id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
          "email": "[email protected]",
          "phone": null,
          "gender": "male",
          "birthday": "1920-01-18",
          "provider": "google",
          "username": "[email protected]",
          "fcm_token": null,
          "is_online": false,
          "toco_city": "Kabupaten Tangerang",
          "toco_name": "Rushman store",
          "created_at": "2024-02-19T09:58:22.121474+00:00",
          "deleted_at": null,
          "toco_phone": "0894949597898",
          "updated_at": "2024-03-21T06:48:28.753426+00:00",
          "profile_kyc": "COMPLETED",
          "display_name": "QA TAD01",
          "toco_address": "Jalan Kampung Tegal, Pagedangan, Pagedangan, Kabupaten Tangerang, Banten",
          "toco_village": "Pagedangan",
          "deleted_email": null,
          "deleted_phone": null,
          "latest_online": "2024-03-20T07:27:08.479458+00:00",
          "toco_district": "Pagedangan",
          "toco_latitude": -6.2942883,
          "toco_province": "Banten",
          "toco_logistics": [
            "0376bc47-0053-459a-b45b-7b0d5114054f",
            "db244b57-1f4d-40b9-afc7-61b97be2a7b3",
            "e6eb1317-f63f-49b9-b6d7-39b63d9870bc",
            "619dc301-28d3-40f8-921e-43d5ad7cfd91",
            "52820f0b-f7c2-40d8-9a52-88d179c9f3bd"
          ],
          "toco_longitude": 106.6378479,
          "profile_picture": "https://lh3.googleusercontent.com/a/ACg8ocLPbK3cDazSOU-a2melZXz28tJnt3_FNpJ9Ex3eqjU8LYs=s96-c",
          "toco_created_at": "2024-02-19T10:01:55.161945+00:00",
          "toco_short_name": "rasman-music-store",
          "tnc_confirmed_at": "2024-02-19T16:58:30.394704+00:00",
          "toco_description": "Gua jual lo beli.",
          "toco_postal_code": 15339,
          "email_confirmed_at": "2024-02-19T09:58:22.141892+00:00",
          "phone_confirmed_at": null,
          "toco_district_code": "36.03.22",
          "toco_banner_picture": "https://toco-img.azureedge.net/static/store_banner/[email protected]",
          "email_confirmed_sent": null,
          "toco_profile_picture": "https://toco-img.azureedge.net/toco/afc4853d-191a-4b48-9255-e711361cf61e-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-hl_image_picker_BOcNuxxim7.jpg",
          "toco_location_description": "Jalan menuju surga"
        },
        "listing": {
          "id": "62d46d17-6935-4ee5-b121-7884172e48b9",
          "lat": -6.2942883,
          "lng": 106.6378479,
          "new": true,
          "sku": "34234234234234234234",
          "city": "Kabupaten Tangerang",
          "fuel": null,
          "slug": "brand-logo-floral-hoodie",
          "sold": 0,
          "type": "177ca046-0278-46d3-9f24-b83e9798a48f",
          "color": null,
          "kudos": null,
          "likes": null,
          "price": 1400000,
          "stock": 1,
          "store": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
          "title": "BRAND LOGO FLORAL HOODIE",
          "views": 7,
          "width": 0,
          "height": 0,
          "length": 0,
          "photos": [
            "https://toco-img.azureedge.net/toco/100f53a9-155d-43cd-a8cc-145bedcca962-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-image_listing_1709745963292.jpg"
          ],
          "weight": 500,
          "deleted": false,
          "mileage": null,
          "archived": false,
          "bold_end": null,
          "category": "af11c431-1020-4dbd-8983-929f61afa784",
          "lot_area": null,
          "sub_type": null,
          "verified": true,
          "min_order": 1,
          "promo_end": null,
          "created_at": "2024-03-06T17:26:05.747263+00:00",
          "created_by": null,
          "daytop_end": null,
          "department": {
            "id": "9cd2e21c-a0d3-4b2a-b86e-d16d46190c96",
            "icon": "https://toco-img.azureedge.net/static/category_icon_7_11_2023/Main%20Category=Olahraga.png",
            "slug": "olahraga",
            "sort": 10,
            "image": null,
            "mobile": "https://toco-img.azureedge.net/static/Toco%20Category%20Banner%20Mobile/Olahraga.jpg",
            "desktop": "https://toco-img.azureedge.net/static/Toco%20Category%20Banner%20Web/Olahraga.jpg",
            "name_en": "Olahraga",
            "name_id": "Olahraga",
            "homepage": true,
            "classified": null,
            "created_at": "2023-07-14T08:43:46.437967+00:00",
            "updated_at": "2023-07-14T08:43:46.437967+00:00",
            "recommended": false,
            "joi_category": null,
            "sort_desktop": 6,
            "darkmode_icon": null,
            "sort_desktop_classified": null
          },
          "facilities": null,
          "tax_expiry": null,
          "thumbnails": [
            "https://toco-img.azureedge.net/toco/100f53a9-155d-43cd-a8cc-145bedcca962-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-image_listing_1709745963292-thumbnail.jpg"
          ],
          "updated_at": "2024-03-18T06:51:07.311066+00:00",
          "updated_by": null,
          "add_to_cart": true,
          "choosen_end": null,
          "description": "Art by Mike Gigliotti\n10 oz 70% Cotton/30% Polyester",
          "rental_type": null,
          "bedroom_area": null,
          "special_bold": null,
          "building_area": null,
          "building_name": null,
          "price_special": null,
          "rental_period": null,
          "special_promo": null,
          "number_of_seat": null,
          "special_daytop": null,
          "number_of_floor": null,
          "production_year": null,
          "special_choosen": null,
          "suggestion_descr": "SKU terlalu panjang",
          "cylinder_capacity": null,
          "legal_certificate": null,
          "number_of_bedroom": null,
          "sub_type_category": null,
          "suggestion_photos": null,
          "transmission_type": null,
          "number_of_bathroom": null,
          "additional_equipment": null,
          "license_plate_category": null
        },
        "user_id": "56a0e777-b96c-4689-93d6-153ccbfa7a89",
        "quantity": 1,
        "store_id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
        "created_at": "2024-03-15T09:18:18.911194+00:00",
        "listing_id": "62d46d17-6935-4ee5-b121-7884172e48b9",
        "updated_at": null
      }
    ],
    "total_product_amount": 1400000,
    "total_amount": 1408000,
    "confirm_expiry": null,
    "shipping_expiry": null,
    "completion_expiry": null,
    "cancellation_reason": "Order Rejected (Auto Cancel Payment Expired)",
    "cancellation_approval_expiry": null,
    "cancellation_description": null,
    "shipping": [
      {
        "id": "a080185e-5366-4d47-990a-a082e350a2c5",
        "provider": "jne",
        "service_name": "JNE OKE",
        "destination_address": "Jalan Terusan Tanjung, Cinere, Kecamatan Cinere, Kota Depok, Jawa Barat",
        "destination_receiver_name": "Salman",
        "destination_phone_number": "081317748855",
        "destination_address_label": "Rumah",
        "estimated_delivery": "23 Mar - 24 Mar",
        "shipping_cost": 8000,
        "weight": 1000,
        "partner_booking_id": null,
        "awb": null,
        "proof_of_delivery": null,
        "tracking_url": null
      }
    ],
    "seller": [
      {
        "id": "3ab1222c-b8cb-4259-9c28-cfd4db84e70b",
        "toco_name": "Rushman store",
        "toco_profile_picture": "https://toco-img.azureedge.net/toco/afc4853d-191a-4b48-9255-e711361cf61e-3ab1222c-b8cb-4259-9c28-cfd4db84e70b-hl_image_picker_BOcNuxxim7.jpg"
      }
    ],
    "buyer": [
      {
        "id": "56a0e777-b96c-4689-93d6-153ccbfa7a89",
        "display_name": "MSA",
        "is_online": true,
        "profile_picture": null
      }
    ]
  },
]
sql postgresql supabase-database
1个回答
0
投票

这些数组是

json_agg()
聚合的直接结果。如果您确定这些子查询保证始终只返回该数组中的单个对象,则可以删除聚合函数(您可以添加
limit 1
来确保):

     (
      select --remove the aggregate function
        /*json_agg(*/json_build_object(
          'id', order_shippings.id, 
          'provider', order_shippings.provider,
          'service_name', order_shippings.service_name,
          'destination_address', order_shippings.destination_address,
          'destination_receiver_name', order_shippings.destination_receiver_name,
          'destination_phone_number', order_shippings.destination_phone_number,
          'destination_address_label', order_shippings.destination_address_label,
          'estimated_delivery', order_shippings.estimated_delivery,
          'shipping_cost', order_shippings.shipping_cost,
          'weight', order_shippings.weight,
          'partner_booking_id', order_shippings.partner_booking_id,
          'awb', order_shippings.awb,
          'proof_of_delivery', order_shippings.proof_of_delivery,
          'tracking_url', order_shippings.tracking_url)/*)*/
          from 
            order_shippings
          where
            order_shippings.order_id = orders.id
          limit 1 --to be sure
      ) as shipping, 

或者您可以随后通过选择第 1 个(第 0 个,因为 json 数组是从 0 开始的)元素将其剥离:

     (
      select 
        json_agg(json_build_object(
          'id', order_shippings.id, 
          'provider', order_shippings.provider,
          'service_name', order_shippings.service_name,
          'destination_address', order_shippings.destination_address,
          'destination_receiver_name', order_shippings.destination_receiver_name,
          'destination_phone_number', order_shippings.destination_phone_number,
          'destination_address_label', order_shippings.destination_address_label,
          'estimated_delivery', order_shippings.estimated_delivery,
          'shipping_cost', order_shippings.shipping_cost,
          'weight', order_shippings.weight,
          'partner_booking_id', order_shippings.partner_booking_id,
          'awb', order_shippings.awb,
          'proof_of_delivery', order_shippings.proof_of_delivery,
          'tracking_url', order_shippings.tracking_url))->0 --here
         --you're taking the first element
          from 
            order_shippings
          where
            order_shippings.order_id = orders.id
      ) as shipping, 

如果这些是

order_shippings
中的所有字段,您不需要在
json_build_object()
中重新构建整个字段 - 您可以让
to_json()
自动处理:

     (
          select 
            to_json(order_shippings)
          from 
            order_shippings
          where
            order_shippings.order_id = orders.id
          limit 1
      ) as shipping, 
© www.soinside.com 2019 - 2024. All rights reserved.