PostgreSQL - Как объединить данные из нескольких строк, используя объединение из других таблиц - PullRequest
0 голосов
/ 02 марта 2020

Я использую postgresql 9.6 и хочу объединить данные из нескольких строк в одну. Я использую 4 таблицы (формат таблицы и данные не могут быть изменены)

Таблицы -

"id" int4 DEFAULT nextval('product_a_seq'::regclass) NOT NULL,
"name" varchar(255) COLLATE "default",
"organization_id" int4,
"description" text COLLATE "default",
"image" varchar(255) COLLATE "default" DEFAULT 'https://abcd.com'::character varying,
"deleted" bool,
"price" float4,
"currency_id" int4,
CONSTRAINT "product_pkey" PRIMARY KEY ("id")
)

CREATE TABLE "public"."product_asset" (
"id" int4 DEFAULT nextval('product_asset_a_seq'::regclass) NOT NULL,
"product_id" int4,
"asset_type" varchar(255) COLLATE "default",
"asset_url" text COLLATE "default",
"asset_value" text COLLATE "default",
"asset_name" text COLLATE "default",
CONSTRAINT "product_asset_pkey" PRIMARY KEY ("id")
)

CREATE TABLE "public"."user" (
"id" int4 DEFAULT nextval('istar_user_a_seq'::regclass) NOT NULL,
"mobile" varchar COLLATE "default",
"name" varchar(255) COLLATE "default",
"organization_id" int4,
CONSTRAINT "istar_user_pkey" PRIMARY KEY ("id")
)

CREATE TABLE "public"."pipeline_product" (
"pipeline_id" int4 NOT NULL,
"product_id" int4 NOT NULL,
CONSTRAINT "uq_pipeline_product_pipeline_id_product_id" UNIQUE ("pipeline_id", "product_id")
)

Для каждого продукта может быть несколько активов и конвейеров

Я хочу, чтобы все данные были сгруппированы в соответствии с product.id, вот моя первоначальная попытка

SELECT
    product. ID AS pid,
    product. NAME AS pname,
    product.price,
    product.currency_id,
    product.description,
    product_asset.asset_type,
    product_asset.asset_url,
    product_asset.asset_name,
    product_asset.asset_value,
    product_asset. ID AS asset_id,
    String_agg (  pipeline_product.pipeline_id :: TEXT, ',' ) AS process_id
FROM
    product
LEFT JOIN product_asset ON product_asset.product_id = product. ID
AND product_asset.is_active = TRUE
LEFT JOIN pipeline_product ON pipeline_product.product_id = product. ID
WHERE
    organization_id IN (
        SELECT
            "user" .organization_id
        FROM
            "user"
        WHERE
            "user" . ID = 218915
    )
AND deleted = FALSE
GROUP BY
    pid,
    product_asset. ID,
    product_asset.asset_type,
    product_asset.asset_name,
    product_asset.asset_url,
product_asset.asset_value

, и я получаю вывод в виде:

sql_op

Мне нужна только одна запись для product.id и всего остального должно быть в одном столбце, я использую функцию string_agg (). Чего мне не хватает?

1 Ответ

0 голосов
/ 02 марта 2020

Я вижу три вопроса в вашем запросе:

  1. product_asset.asset_url не уникален, использование max(product_asset.asset_url)
  2. product_asset.ID не уникально, поэтому вы не можете сгруппировать его. Использование min(product_asset.ID) или max(product_asset. ID)
  3. String_agg(pipeline_product.pipeline_id :: TEXT, ',') не всегда возвращает одно и то же значение, поскольку они не отсортированы. Вы должны добавить ORDER BY pipeline_product.product_id, pipeline_product.pipeline_id.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...