MYSQL сопоставить несколько строк в одной таблице с несколькими идентификаторами

Опция заключается в использовании grouped измерительных переменных data.table::melt как:

library(data.table)


melt(setDT(x), id=1:2, measure=list(c("t2","t3"), c("y2","y3"), c("se2","se3")), 
                                  value.name=c("t2", "y2", "se2"))

#Or in short form
melt(setDT(x), id=1:2, measure=patterns("^t[2-3]", "^y", "^se"),
                       value.name=c("t2", "y2", "se2"))
#        id t1 variable t2  y2 se2
# 1: Study1  1        1  2 0.1 0.5
# 2: Study1  1        2  3 0.2 0.7
0
задан Strawberry 18 January 2019 в 22:01
поделиться

1 ответ

Требуются group by и having:

SELECT v.vendor_id
FROM vendors v  -- Shouldn't this be called vendorProducts ?
WHERE v.product_id IN (10, 20, 30, 40, 50) 
GROUP BY v.vendor_id
HAVING COUNT(DISTINCT v.product_id) = 5;

. Для нескольких поставщиков вы можете расширить вышеуказанную логику. Идея состоит в том, чтобы объединить таблицу, чтобы получить список пар поставщиков и всех продуктов, которые они вместе имеют. Затем выполните ту же логику, что и выше:

SELECT v.vendor_id1, v.vendor_id2
FROM (SELECT DISTINCT v1.vendor_id as vendor_id1, v2.vendor_id as vendor_id2,
             (CASE WHEN n.n = 1 THEN v1.product_id ELSE v2.product_id END) as product_id
      FROM vendors v1 JOIN
           vendors v2
           ON v1.product_id <> v2.product_id AND
              v1.vendor_id < v2.vendor_id CROSS JOIN
           (SELECT 1 as n UNION ALL SELECT 2) n
      UNION ALL
      -- Then include the singletons, just in case
      SELECT v.vendor_id, NULL, v.product_id
      FROM vendors v
     ) v
WHERE v.product_id IN (10, 20, 30, 40, 50) 
GROUP BY v.vendor_id1, v.vendor_id2
HAVING COUNT(DISTINCT v.product_id) = 5;

На самом деле вы можете выполнить фильтрацию товаров в подзапросе - чтобы сделать запрос более эффективным. Что касается того, чтобы сделать это более общим, «5» - это количество предметов. Я не знаю, как создается окончательный запрос.

РЕДАКТИРОВАТЬ II:

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

select v1.*, v2.*
from (select vendor_id,
             max(product_id = 1) as p1,
             max(product_id = 2) as p2,
             max(product_id = 3) as p3,
             max(product_id = 4) as p4,
             max(product_id = 5) as p5,
      from vendors
      where product_id in (1, 2, 3, 4, 5)
      group by vendor_id
     ) v1 join
     (select vendor_id,
             max(product_id = 1) as p1,
             max(product_id = 2) as p2,
             max(product_id = 3) as p3,
             max(product_id = 4) as p4,
             max(product_id = 5) as p5,
      from vendors
      where product_id in (1, 2, 3, 4, 5)
      group by vendor_id
     ) v2
     on (v1.p1 + v2.p1) > 0 and
        (v1.p2 + v2.p2) > 0 and
        (v1.p3 + v2.p3) > 0 and
        (v1.p4 + v2.p4) > 0 and
        (v1.p5 + v2.p5) > 0;

Примечание. Если у одного поставщика есть все продукты, он будет отображаться в паре с любым другим поставщиком.

0
ответ дан Gordon Linoff 18 January 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: