Объединение и объединение двух таблиц в PostgreSQL - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь создать сводную таблицу вывода, используя агрегаты из двух разных таблиц. Я не понимаю, как объединить два результата. Две таблицы, в одной из которых перечислены все продукты в каждом магазине, а в другой - изменение цен на каждый продукт, представлены ниже.

| product_id | daily_price | date       |
|------------|-------------|------------|
| 1          | 1.25$       | 01-01-2000 |
| 1          | ...         | ...        |
| 1          | 1$          | 31-12-2000 |
| 2          | 4.5$        | 01-01-2000 |
| 2          | ...         | ...        |
| 2          | 4.25$       | 31-12-2000 |

| store_id | product_id |
|----------|------------|
| 1        | 1          |
| 1        | 2          |
| 2        | 1          |
| 2        | 3          |
| 3        | 2          |

Первая агрегация получает среднюю дневную цену (она варьируется) всех продуктов.

SELECT product_id, ROUND((AVG(price)),2) as average_price FROM product_dailyprices
    GROUP BY product_id;

| product_id | average_price |
|------------|---------------|
| 1          | 50            |
| 2          | 100           |
| 3          | 250           |

Второй запрос дает мне количество различных продуктов, доступных в каждом магазине

SELECT store, COUNT(product_id) as product_count FROM products
    GROUP BY store;

| store_id | product_count |
|----------|---------------|
| 1        | 200           |
| 2        | 250           |
| 3        | 225           |

Я немного не понимаю, как выполнить запрос, чтобы получить следующее:

| store_id | product_count | average_price_at_store |
|----------|---------------|------------------------|
| 1        | 34            | 6.51$                  |
| 2        | 45            | 3.23$                  |
| 3        | 36            | 5.37$                  |

Спасибо за помощь!

1 Ответ

1 голос
/ 27 мая 2020

Поскольку вы не указали SQL для таблиц, давайте воспользуемся следующей пустой структурой:

CREATE TABLE products
(
    id   SERIAL NOT NULL,
    name text   NOT NULL,

    CONSTRAINT products_pk PRIMARY KEY (id)
);

CREATE TABLE stores
(
    id   SERIAL NOT NULL,
    name text   NOT NULL,

    CONSTRAINT stores_pk PRIMARY KEY (id)
);

CREATE TABLE daily_prices
(
    product_id  INTEGER          NOT NULL,
    daily_price DOUBLE PRECISION NOT NULL,
    date        timestamptz,

    CONSTRAINT daily_prices_product FOREIGN KEY (product_id) REFERENCES products (id)
);

CREATE TABLE locations
(
    store_id   INTEGER NOT NULL,
    product_id INTEGER NOT NULL,

    CONSTRAINT products_product_fk FOREIGN KEY (product_id) REFERENCES products (id),
    CONSTRAINT products_store_fk FOREIGN KEY (store_id) REFERENCES stores (id)
);

И позвольте ввести некоторые образцы данных, чтобы проверить, работает ли запрос:

INSERT INTO products(name)
VALUES ('product 1');

INSERT INTO products(name)
VALUES ('product 2');


INSERT INTO products(name)
VALUES ('product 3');

INSERT INTO stores(name)
VALUES ('store 1');

INSERT INTO stores(name)
VALUES ('store 2');

insert into locations (store_id, product_id)
values (1, 1),
       (1, 2),
       (2, 2),
       (2, 3);



INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (1, 2.0, '01-01-2020');

INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (1, 4.0, '02-01-2020');

INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (2, 3.0, '01-01-2020');

INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (2, 5.0, '02-01-2020');

INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (3, 10.0, '01-01-2020');

INSERT INTO daily_prices(product_id, daily_price, date)
VALUES (3, 20.0, '02-01-2020');

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

select l.store_id                   as store_id,
       count(distinct l.product_id) as number_of_products,
       avg(dp.daily_price)          as average_price
from locations l
         join daily_prices dp on dp.product_id = l.product_id
group by l.store_id;

И мы можем вручную проверить, что он рассчитал ожидаемый результат:

+--------+------------------+-------------+
|store_id|number_of_products|average_price|
+--------+------------------+-------------+
|1       |2                 |3.5          |
|2       |2                 |9.5          |
+--------+------------------+-------------+
...