Если у вас была таблица ColLookup, как это:
SubType, ColumnName
1,wf1.Id
2,wf1.Id
3,wf1.Id
4,wf1.Id
1,wf1.Name
2,wf1.Name
5,wf1.OtherNames
6,wf1.OtherNames
8,wf1.OtherNames
1,wf1.CountryName
2,wf1.CountryName
Тогда такой SQL-код даст вам имена столбцов, которые вы должны извлечь:
SELECT
STRING_AGG(l.ColumnName, ',') as ColList
FROM
otherTable o
INNER JOIN
ColLookup l on o.subtype = l.subtype
WHERE
o.id = 1234
Если бы подтип o.id 1234 был 1, этот SQL вернул бы
'wf1.Id,1,wf1.Name,wf1.CountryName'
Если бы подтип o.id X был 3, этот SQL вернул бы
'wf1.Id'
Создание полноценного SQL может выглядеть примерно так:
SELECT
CONCAT('SELECT ', STRING_AGG(l.ColumnName, ','), ' FROM blah') as sq
FROM
otherTable o
INNER JOIN
ColLookup l on o.subtype = l.subtype
WHERE
o.id = 1234
Вы можете присвоить это переменной и EXEC это
Если ваш SQLS выпущен до 2017 года и не имеет STRING_AGG, используйте аналогичный метод объединения нескольких строк в одну строку, например STUFF / FOR XML PATH. Если требуется определенный порядок, добавьте столбец порядка в таблицу поиска (STRING_AGG имеет параметр WITHIN GROUP ORDER BY, я уверен, что другие методы также имеют параметры для изменения порядка объединенной строки)
Правда, я бы сделал это на C #. Я бы запустил основной запрос, который выбирает все, а затем я бы запустить:
SELECT ColName FROM ColLookup WHERE SubType in (1,5)
Я бы поместил его в словарь / хэш-набор (это с использованием псевдокода linq, но как вам угодно):
//this is a union - anything 1 can see or 5 can see
var dict = dbcontext.Wf1Table.Where(r => r == 1 || r == 5).Distinct().ToDictionary(r => r.ColumnName, r => r.ColumnName)
//this is an intersect - anything common to 1 and 5 only
var dict = dbcontext.Wf1Table.Where(r => r == 1).Intersect(dbcontext.Wf1Table.Where(r => r == 5)).ToDictionary(r => r.ColumnName, r => r.ColumnName)
//this is if you downloaded the columns into a datatable
//SELECT DISTINCT colname FROM t WHERE subtype IN (1,5) --union
//SELECT colname FROM t WHERE subtype IN (1,5) GROUP BY colname HAVING COUNT(*) = 2 --intersection
var dict = new Dictionary(string, string);
foreach(var ro in colnamedatatable)
dict[ro.ColName] = null;
И я бы перетащил свой основной запрос в таблицу данных и удалил ненужные столбцы:
for(int c = datatable.Columns.Length -1; c >= 0; c--) //gobackwards
if(!dict.ContainsKey(datatable.Columns[c].ColumnName))
datatable.Columns.RemoveAt(c);
Если вы хотите упорствовать в этом в SQL, это даст пересечение:
SELECT
CONCAT('SELECT ', STRING_AGG(l.ColumnName, ','), ' FROM blah') as sq
FROM
otherTable o
INNER JOIN
ColLookup l on o.subtype = l.subtype
WHERE
o.id = @id
GROUP BY
l.ColumnName
HAVING COUNT(*) = @count_of_subtypes_for_that_id
Что-то должно знать, сколько подтипов существует для данного идентификатора; БД знает, но вам трудно руководствоваться этим, потому что вы еще не сказали, как хранятся данные. Если это правильно (несколько записей идентификаторов / таблица посредников), тогда этот запрос работает. Если это «список, разделенный запятыми», тогда (тьфу) он нуждается в разборе на две строки