Поиск значения столбца, у которого есть пара записей с некоторыми различными указанными значениями - PullRequest
0 голосов
/ 29 июня 2018

У меня есть база данных:

|id|surname|name
| 1|Smith  |John
| 2|Smith  |Mike
| 3|Smith  |Bob
| 4|Knope  |John
| 5|Knope  |Mike
| 6|Knope  |Dick
| 7|Pratt  |John
| 8|Pratt  |Jill
| 9|Pratt  |James

и я хочу найти фамилию, в которой есть Джон, Майк и Боб. Я хочу, чтобы это вернуло Смита. Или я хочу найти семью, в которой есть Джон и Майк, и я хочу, чтобы она вернула Смита и Ноупа. Как я могу это сделать?

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

|surname|
|Smith  |

Тогда я хочу искать только Джона и Майка и хочу получить:

|surname|
|Smith  |
|Knope  |

Ответы [ 4 ]

0 голосов
/ 29 июня 2018

Возможно, это не лучший способ сделать это, но вы можете попробовать следующее для Postgresql:

select * 
from
(
select 
    concat(',' , string_agg(name1,',') , ',') as X,
    surname
from 
    table_name as A
group BY 
    surname
) As B
Where B.X like '%,John,%' And B.X like '%,Mike,%' And B.X like '%,Bob,%';

SQLFIDDLE DEMO

Следующее для SQL-сервера:

select * from
(
select 
    ', ' + STUFF((SELECT ', ' + name1 FROM table_name WHERE surname = A.surname FOR XML PATH('')),1,2,'') + ',' as X,
    surname
from 
    table_name as A
group BY 
    surname
) as B
Where B.X like '%, John,%' And B.X like '%, Mike,%' And B.X like '%, Bob,%';

SQLFIDDLE DEMO

0 голосов
/ 29 июня 2018

Ваш вход имеет динамически несколько значений. Таким образом, я предполагаю, что вы поместили все имена, которые вы хотите включить в семейство, в таблицу #i с полем «имя». Затем вы хотите, чтобы все семейства, для которых не указано имя, указанное в ваших входных данных, отсутствуют.

select *
from (select distinct surename from yourtable)surnames
where not exists
(
    select 1 from #i
    where not exists
    (
        select 1 
        from yourtable t
        where 
            t.surename=surnames.surename
            and #i.name=t.name
    )
)
0 голосов
/ 29 июня 2018

Это работает в SQL Server - написано до того, как ваш вопрос был помечен PostgreSQL.

Настройка данных теста:

DECLARE @Names TABLE (ID INTEGER IDENTITY, Surname VARCHAR(50), Forenames VARCHAR(50));

INSERT
    @Names (Surname, Forenames)
VALUES
    ('Smith', 'John'),
    ('Smith', 'Mike'),
    ('Smith', 'Bob' ),
    ('Knope', 'John'),
    ('Knope', 'Mike'),
    ('Knope', 'Dick'),
    ('Pratt', 'John'),
    ('Pratt', 'Jill'),
    ('Pratt', 'James');

Объявите табличную переменную, содержащую имена, которые вы хотите сопоставить. Это действует как параметр, поэтому вы должны отредактировать значения, которые мы вставили, чтобы проверить результаты:

DECLARE @ForenamesToSearch TABLE (Forenames VARCHAR(50));

INSERT
    @ForenamesToSearch
VALUES
    ('John')
    , ('Mike')
    , ('Bob');

Наконец, мы используем GROUP BY и HAVING COUNT, чтобы обеспечить точное совпадение количества имен.

SELECT
    Surname
FROM
    (SELECT DISTINCT Forenames, Surname FROM @Names) Names
    INNER JOIN @ForenamesToSearch Forenames ON Names.Forenames = Forenames.Forenames
GROUP BY
    Surname
HAVING
    COUNT(1) = (SELECT COUNT(1) FROM @ForenamesToSearch);
0 голосов
/ 29 июня 2018

На основании ваших объяснений вы можете сделать что-то вроде этого:

declare @table table (it int, surename varchar(50),name1 varchar(50))

insert into @table

values
(1,'Smith','John'),
(2,'Smith','Mike'),
(3,'Smith','Bob' ),
(4,'Knope','John'),
(5,'Knope','Mike'),
(6,'Knope','Dick'),
(7,'Pratt','John'),
(8,'Pratt','Jill'),
(9,'Pratt','James')

select * from @table
where name1 in ('john','mike','bob') and surename = 'smith'

union 

select * from @table
where name1 in('john','mike') and surename in ('smith','knope')

Результат

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...