搜索具有一些具有不同指定值的记录的列值

时间:2018-06-29 09:15:53

标签: sql postgresql

我有一个数据库:

|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  |

然后我只想查找John和Mike,而我想要得到:

|surname|
|Smith  |
|Knope  |

4 个答案:

答案 0 :(得分:0)

根据您的移植物,您可以执行以下操作:

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

答案 1 :(得分:0)

您的输入具有动态多个值。因此,我假设您已经将希望家族包含的所有名称都放在表“ 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
    )
)

答案 2 :(得分:0)

这在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);

答案 3 :(得分:0)

可能不是最好的方法,但是您可以在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 Server:

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