Nano Hash - криптовалюты, майнинг, программирование

SQL группирует продукты и сообщения по

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

product_id creation_date user_id category_id
p1 2017-03-01 u1 c1
p2 2018-05-23 u1 c3
p3 2019-06-21 u2 c1

таблица сообщений выглядит так:

message_id creation_date product_id user_from
m1 2018-03-01 p1 u2
m2 2019-08-19 p1 u5
m3 2020-10-10 p3 u7

Я хочу перечислить все продукты в категории, отсортированные по общему количеству сообщений, а также 5 основных покупателей каждого продукта (пользователи, которые связались с этими продуктами, отсортированные по общему количеству отправленных сообщений)

Пример выходной таблицы:

category_id product_id total_messages_for_product user_id messages
c1 p1 200 u1 10
c1 p1 200 u2 9
c1 p1 200 u3 7
c1 p1 200 u4 5
c1 p1 200 u5 4
c1 p2 150 u7 11
c1 p2 150 u8 10
c1 p2 150 u9 9
c1 p2 150 u10 7
c1 p2 150 u4 6

  • Итак, что вы пробовали? 04.01.2021
  • Ваши существующие входные данные не имеют смысла. Почему в таблице products есть столбец user_id? 04.01.2021
  • Я знаю, как получить сообщения category_id, product_id и group by sum с помощью внутреннего соединения, я не знаю, как получить два последних столбца @Russ 04.01.2021
  • @mathguy продукт создан каким-то пользователем, однако этот user_id отличается от столбца сообщений user_from, который показывает пользователя, отправившего сообщение. надеюсь, это проясняет 04.01.2021
  • Но тогда, я просто предполагаю, вам нужно user_from на выходе (из второй таблицы), а не user_id. Верно? 04.01.2021
  • да точно @mathguy 04.01.2021

Ответы:


1

Вы, кажется, хотите:

SELECT p.category_id,
       p.product_id,
       m.total_messages_for_product,
       m.user_from AS user_id,
       m.messages
FROM   products p
       INNER JOIN (
         SELECT product_id,
                user_from,
                COUNT(*) AS messages,
                SUM( COUNT(*) ) OVER ( PARTITION BY product_id )
                  AS total_messages_for_product,
                RANK() OVER (
                  PARTITION BY product_id ORDER BY COUNT(*) DESC
                ) AS messages_rank
         FROM   messages
         GROUP BY product_id, user_from
       ) m
       ON ( p.product_id = m.product_id )
WHERE  m.messages_rank <= 5;

(Примечание: вместо этого вы можете использовать ROW_NUMBER, чтобы получить первые 5 записей без совпадений, а не RANK, которое возвращает первые 5 записей с совпадениями.)

Что для ваших образцов данных:

CREATE TABLE products ( product_id, creation_date, user_id, category_id ) AS
SELECT 'p1', DATE '2017-03-01', 'u1', 'c1' FROM DUAL UNION ALL
SELECT 'p2', DATE '2018-05-23', 'u1', 'c3' FROM DUAL UNION ALL
SELECT 'p3', DATE '2019-06-21', 'u2', 'c1' FROM DUAL;

CREATE TABLE messages( message_id, creation_date, product_id, user_from ) AS
SELECT 'm1', DATE '2018-03-01', 'p1', 'u2' FROM DUAL UNION ALL
SELECT 'm2', DATE '2019-08-19', 'p1', 'u5' FROM DUAL UNION ALL
SELECT 'm3', DATE '2020-10-10', 'p3', 'u7' FROM DUAL;

Выходы:

CATEGORY_ID | PRODUCT_ID | TOTAL_MESSAGES_FOR_PRODUCT | USER_ID | MESSAGES
:---------- | :--------- | -------------------------: | :------ | -------:
c1          | p1         |                          2 | u5      |        1
c1          | p1         |                          2 | u2      |        1
c1          | p3         |                          1 | u7      |        1

db‹›fiddle здесь

04.01.2021

2

Что-то вроде этого (не проверено, так как вы не предоставили тестовые данные в пригодной для использования форме):

with
  agg (product_id, user_from, messages, total_messages_for_product) as (
    select product_id, user_from, count(*),
           sum(count(*)) over (partition by product_id)
    from   messages
    group  by product_id, user_from
  )
select p.category_id, a.product_id, a.total_messages_for_product,
       a.user_from, a.messages
from   products p join agg a on p.product_id = a.product_id
order  by product_id, user_from   --  if/as needed
;

Основная работа выполняется в подзапросе agg (используется только таблица messages). Обратите внимание на использование аналитической функции sum(), разделенной по продуктам, для получения общего количества сообщений по продуктам. Затем вы получаете category_id, присоединившись к таблице products.

04.01.2021
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..