2016-04-09 2 views
4

Как я могу назвать имена всех членов группы с одинаковой фамилией?Как найти второе значение внутри столбца

Столбец имеет значения, как этот

band_NAME 
------------------- 
Carla Thomas 
Stephen E. Rice 
Cynthia P. Tree 
Richard Anthony Paul 
Ann Frances Smith 
Lorace Black 
Timothy Adam Paul 

Я знаю, мы должны использовать instr и substr. Я просто не понимаю, как мы будем определять позицию.

Я знаю, что базовый формат будет как

SELECT band_NAME 
FROM TABLE 
where substr(band_name, ?, instr() IN 
    (select substr(band_name, ?, instr()-1) 
    from table 
    group by SUBSTR(band_NAME , ?, INSTR()-1) 
    HAVING COUNT(*) > 1); 

Но то, что происходит в вопросительных знаков и внутри instr?

Поблагодарили бы за помощь!

+0

Как это должно работать? В «Джерри Ли Льюис» первое имя - «Джерри Ли», фамилия «Льюис», поэтому вы разделили имя и фамилию на последнем бланке. В «Gabriel García Márquez» первое имя - «Gabriel», а фамилия - «García Márquez», т. Е. Вы разделились на первом бланке. Существуют также такие названия, как «Хуан Луис Гарсиа Пералес», где он не является ни первым, ни последним пробелом, который отделяет первую и фамилию. Тогда подумайте о китайских именах, где фамилия на первом месте. –

+0

Да, точно, я не понимаю, как разбить его.Некоторые из перечисленных выше имен имеют среднюю начальную, поэтому ее можно разделить по истечении периода, но как и для других с тремя именами, я понятия не имею, как это сделать. Просто нужно выяснить способ найти совпадение на фамилии и отобразить их. – Bob

+0

Я хочу сказать, что вы не можете получить то, что является именем и фамилией только от полного имени. Вы должны иметь больше информации. Может быть, словарь первых и фамилий. (И даже тогда «Пол» может быть как первым, так и фамилией). Может быть, вы в порядке с компромиссом. Но вам решать, какие правила вы будете в порядке. –

ответ

0

Я предполагаю, что ваш разделитель между именем и фамилией является одним пробелом. Больше пробелов в строке является частью имени. Таким образом, вы, вероятно, захотите выполнить поиск первого символа пробела.

Возвращаемое положение первого вхождения подстроки с instr(str, substr).

Затем используйте substring(str, pos), чтобы вернуть подстроку, начинающуюся с заданного положения (подача по функции instr).

SELECT substring(band_name, instr(band_name, ' ')) 
FROM yourtable 
+0

Я пробовал эту попытку, прежде чем я разместил вопрос, но он не работает должным образом :( – Bob

+1

@Bob: Это doesn «Нет, скажите« Считайте меня что-нибудь ». Что значит« это не работает должным образом, к сожалению »? –

+0

К сожалению, я начинаю начинать с этого. Когда я пробовал код выше, он сказал« недействительный ».. – Bob

0

Попробуйте это:

SELECT t1.band_NAME 
FROM TABLE t1 LEFT JOIN TABLE t2 
ON SUBSTRING_INDEX(t1.band_name, ' ', - 1) = SUBSTRING_INDEX(t2.band_name, ' ', - 1) 
WHERE t1.band_name <> t2.band_name 

И это, как ваш псевдокод MySQL:

SELECT band_NAME FROM TABLE 
Where FIND_IN_SET (SUBSTRING_INDEX(band_name, ' ', -1), 
(Select SUBSTRING_INDEX(band_name, ' ', -1) bn 
From TABLE Group by bn 
having Count(bn) > 1 
) 
) 

SQL Server

SELECT band_NAME FROM TABLE 
Where 
SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name] 
IN 
(Select SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name] 
From TABLE Group by [Last Name] -- or SUBSTRING(band_NAME, CHARINDEX(' ', band_NAME) + 1, LEN(band_NAME)) AS [Last Name] 
having Count(*) > 1 
) 
) 

Кроме того, я думаю, что вы можете извлечь выгоду из STRING_SPLIT в некотором роде

+0

Это не работает :(говорит, что неожиданный конец команды SQL – Bob

+0

Я пробовал, и он отлично работал с me, Можете ли вы убедиться, что скобки закрыты правильно? и вы меняете 'TABLE' в 2-х местах с вашим реальным именем таблицы? @Bob – wajeeh

+0

с вашим ex act query говорит «неожиданный конец команды sql». Я использую SQL-разработчик, если это имеет значение ..? Он не распознает «индекс подстроки», поэтому я заменил его на substr после добавления другой скобки. Затем он говорит, что «bn» - это «недействительный оператор - не существует». – Bob

0

Try This

with cte as 
(
select band_name, ROW_NUMBER() over(partition by SUBSTRING(band_name,CHARINDEX(' ',band_name),LEN(band_name)) order by band_name) as cnt, 
     SUBSTRING(band_name,CHARINDEX(' ',band_name),LEN(band_name)) as lastname 
from your_table 
) 
select band_name 
from cte 
where lastname in (select lastname from cte where cnt > 1) 
0

хорошо,

Лучшее решение для изменения схемы и хранить фамилию в отдельной колонке.

В то же время вы могли бы получить фамилию, как это,

SELECT 
      [band_NAME], 
      CASE WHEN CHARINDEX(' ', [band_NAME]) > 0 
       THEN 
        RIGHT([band_NAME], CHARINDEX(' ', REVERSE([band_NAME]))) 
       ELSE 
        [band_NAME] 
      END [LastName] 
    FROM 
      [TABLE] 

Вы можете затем сгруппировать их, как этот

SELECT 
      [LastName], 
      COUNT(*) 
    FROM 
     (
      SELECT 
        [band_NAME], 
        CASE WHEN CHARINDEX(' ', [band_NAME]) > 0 
         THEN 
          RIGHT([band_NAME], CHARINDEX(' ', REVERSE([band_NAME]))) 
         ELSE 
          [band_NAME] 
        END [LastName] 
       FROM 
        [TABLE] 
     ) [TABLEWithLastName] 
    GROUP BY 
      [LastName]; 
Смежные вопросы