Просто, чтобы избежать быстрых ответов, я упомяну, что я не использую MySQL, поэтому я не могу использовать GROUP_CONCAT, и что я также рассмотрел этот вопрос уже.
Пример
(это не те данные, с которыми я работаю, но они точно описывают мой случай)
Персональная таблица, с идентификатором, столбцы Имя
Таблица Person_CountriesVisited с столбцами PersonID, Country (таблица связей 1..M)
Таблица Person_StatesVisited с PersonID, столбцы State (таблица ссылок 1..M)
Ограничения
Я не могу изменить БД. Я также не могу изменить большую часть кода, так что это должно быть сделано в SQL, а не в коде после выполнения запроса.
Желаемый результат
Результирующий набор со столбцами
Person.ID,
Person.Name,
[список связанных Person_CountriesVisited.Country],
[список связанных Person_StatesVisited.State],
который также может быть отфильтрован общим поисковым термином, который применяется ко всем столбцам.
Мои попытки
Теперь, мой SQL-фу не такой уж и острый в наши дни, но я делаю все, что могу, основываясь на примерах, которые я нашел.
1) Я пытался использовать скалярный подзапрос:
ВЫБРАТЬ P.ID, P.Name,
(выберите
CV.Country + ','
ОТ
Person_CountriesVisited CV ON P.ID =
CV.PersonId
ДЛЯ ПУТИ XML ('')) AS
Страны, которые посетили,
(ВЫБРАТЬ
SV.State + ','
FROM
Person_StatesVisited SV ON P.ID =
SV.PersonId
FOR XML PATH ('')) ASSVisited
ОТ ЛИЧНОСТИ P
ГДЕ P.Name LIKE
'%' + @SearchTerm + '%'
ИЛИ
СтраныПосещенные как "%" +
@SearchTerm + '%'
ИЛИ StatesVisted
LIKE '%' + @SearchTerm + '%'
Который возвращает данные, которые я хочу, но только когда я удаляю предложение WHERE. Он не работает с предложением WHERE, потому что SQL Server 2005, похоже, не нравится, что я ссылаюсь на столбец, созданный из скалярного подзапроса в предложении WHERE. Это выдает мне сообщение об ошибке «Неверное имя столбца« Страны, в которых вы находитесь »» (и снова для столбца «Посещенные Штаты»).
2) Я попробовал трюк с применением кросса:
ВЫБРАТЬ P.ID, P.Name, Страны, которые посетили,
Посещенные Штаты
ОТ ЛИЦА П
INNER JOIN Person_CountriesVisited CV ON
P.ID = CV.PersonID
ПРИМЕНИТЬ КРЕСТ
(
ВЫБЕРИТЕ CV.Country + ','
ОТ ЧЕЛОВЕКА P2 ВНУТРЕННЯЯ РЕШЕНИЕ
Person_CountriesVisited CV ON P2.ID =
CV.PersonID
ГДЕ P.ID =
P2.ID
ДЛЯ ПУТИ XML ('')
)
PRE_TRIMMED (посещенные страны)
INNER JOIN Person_StatesVisited SV ON
P.ID = SV.PersonID
CROSS APPLY (
ВЫБРАТЬ SV.State +
','
ОТ ЛИЦА P2 ВНУТРЕННЕЕ ПРИСОЕДИНЕНИЕ
Person_StatesVisited SV ON P2.ID =
SV.PersonID FOR XML PATH ('')
)
PRE_TRIMMED (StatesVisited)
ГДЕ
P.Name LIKE '%' + @SearchTerm +
"%"
ИЛИ Страны, которые посещали, КАК "%"
+ @SearchTerm + '%'
ИЛИ StatesVisted LIKE '%' + @SearchTerm +
'%'
Но это тоже не работает, так как вы, очевидно, не можете иметь несколько вызовов pre_trimmed.
У кого-нибудь есть предложения для меня?