Опция заключается в использовании 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
Требуются 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;
Примечание. Если у одного поставщика есть все продукты, он будет отображаться в паре с любым другим поставщиком.