Конкретный ответ ...
SELECT
ActionName
FROM
yourTable
WHERE
SourceName in ('S01', 'S02')
GROUP BY
ActionName
HAVING
COUNT(DISTINCT SourceName) = 2
Возможно, быстрее для вашего конкретного вопроса ...
SELECT
a.SourceName
FROM
yourTable AS a
INNER JOIN
yourTable AS b
ON a.ActionName = b.ActionName
WHERE
a.SourceName = 'S01'
AND b.SourceName = 'S02'
Общий ответ ...
SELECT
ActionName
FROM
yourTable
INNER JOIN
tableWithSourceNames
ON yourTable.SourceName = tableWithSourceNames.SourceName
GROUP BY
ActionName
HAVING
COUNT(DISTINCT yourTable.SourceName) = (SELECT COUNT(DISTINCT SourceName) FROM tableWithSourceNames)
Оказывается, это очень плохо масштабируется (поскольку размер вашей таблицы увеличивается, производительность падает). Вы можете оптимизировать, хотя ...
Имея немного метаданных о том, насколько избирательным является каждое SourceName ...
CREATE TABLE sourceNameMetaData (
sourceName VARCHAR(64),
occurances INT
)
Я бы порекомендовал обновлять этот талб с помощью триггера или чего-то еще. Затем вы можете отфильтровать таблицу ActionTable по наиболее ограничивающей записи, а затем выполнить оставшуюся логику как обычно.
SELECT
yourTable.ActionName
FROM
(
SELECT
ActionName
FROM
(
SELECT
sourceName
FROM
sourceNameMetaData
INNER JOIN
tableWithSourceNames
ON tableWithSourceNames.SourceName = sourceNameMetaData.SourceName
ORDER BY
occurances ASC
LIMIT
1
)
AS filter
INNER JOIN
yourTable
ON yourTable.SourceName = filter.SourceName
GROUP BY
ActionName
)
AS filter
INNER JOIN
yourTable
ON yourTable.ActionName = filteredData.ActionName
INNER JOIN
tableWithSourceNames
ON yourTable.SourceName = tableWithSourceNames.SourceName
GROUP BY
yourTable.ActionName
HAVING
COUNT(DISTINCT yourTable.SourceName) = (SELECT COUNT(DISTINCT SourceName) FROM tableWithSourceNames)
Примечания:
- Эта оптимизация не нужна для небольших таблиц
- Эта оптимизация предполагает, что у вас есть индексы ОБА (имя-источника, имя-действия) И (имя-действия, имя-источника)
- Это замечательный пример, который я использую, чтобы показать, что больше кода МОЖЕТ быть быстрее