如何找到拥有两个特定许可证的人,单独的行,只有一个具有有限许可证
How find people with two specific licenses, separate rows, only one with limited permit
我正在尝试组合一个查询,这样我就可以在我们的数据库中找到既有 NY permit/license 也有有限 permit/license 的人,但是这些行是单独的行询问。我只想要那些没有纽约州驾照的,那里是有限制的。
这是我目前拥有的:
p.Last_Name
,p.First_Name
,p.Middle_Initial
,p.person_id
,i.Document
,i.Expiration_date
,i.Updated_Date
--,i.IssueDate
--,i.Historical
--,i.Comments
--,f.Current_status
,i.State
from dbo.PersonDoc_ID_Numbers i
inner join "DB"."dbo"."People" p on p.person_id = i.person_id
inner join person_facilities f on p.person_id = f.person_id
where
(Document like '%limited%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null))) or
(Document like '%NY%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null)))
and f.current_status in ('Active')
and i.Historical != 1
order by p.Last_Name
所以这 return 对某些人来说是这样的,但我不想要拥有纽约执照的人以及有限的人;我只想要没有纽约牌照的限量版:
Last_Name First_Name Middle_Initial person_id Document Expiration_date Updated_Date
GG FF L. 123 Limited Permit 2019-09-23 2018-10-04 456
GG FF L. 123 NY State License NULL 2018-11-13
Smith Tony L. 456 Limited Permit 2019-09-23 2018-10-04 456
Snoopy Dog L. 789 NY State License NULL 2018-11-13
所以对于 FF GG,我对她的名字被 returned 不感兴趣,因为她有任何执照,而且是有限的。我只想要有限的。但我希望 return Tony Smith 就是这样。
*Update as requested:
dbo.PersonDoc_ID_Numbers
person_id Expiration_date State license_NO Updated_Date Historical Document
1 2019-9-22 NY 2 2018-10-04 0 Limited Perm *
1 null NY no 2019-4-17 0 NY State
2 null NY 3 2011-06-30 0 Limited Lic
2 null NY 4 2011-06-14 0 NY State
3 2018-5-04 NY 5 2018-05-01 0 Limited Perm*
4 2019-08-29 NY 6 2018-01-12 0 Limited Lic *
5 null null 7 2016-4-20 0 Jujufication
5 null NY 8 2018-4-05 0 NY State
6 2016-07-15 OH 9 2018-01-09 0 Snoopyism
dbo.Person_Facilities
person_id Current_status
1 Active
2 Active
3 Active
4 Active
5 Active
6 Active
dbo.Person
person_id First Last
1 GG FF
2 MM PP
3 Tony Smith
4 Snoopy Dog
5 Sarah Gd
6 Bethany Yoda
我在 id table 中的那些旁边放了一个 *,它们应该在最后一组。请注意,事实证明 FF GG 没有执照号码,因此她需要在最后一组。
假设您当前的查询一切正常,您可以使用 COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
来确定查询将生成多少行,然后 select
只有单行的条目以及沿着这些行的查询:
WITH myCte AS (
SELECT
p.Last_Name
,p.First_Name
,p.Middle_Initial
,p.person_id
,i.Document
,i.Expiration_date
,i.Updated_Date
,i.IssueDate
,i.Historical
,i.Comments
,f.Current_status
,i.State as DocumentState
,COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
from dbo.PersonDoc_ID_Numbers i
inner join "DB"."dbo"."People" p on p.person_id = i.person_id
left join person_facilities f on p.person_id = f.person_id
where
(Document like '%limited%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null))) or
(Document like '%NY%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null)))
and f.current_status in ('Active')
and i.Historical != 1
)
SELECT Last_Name
,First_Name
,Middle_Initial
,person_id
,Document
,Expiration_date
,Updated_Date
,IssueDate
,Historical
,Comments
,Current_status
,DocumentState
FROM myCte
WHERE noOfRows = 1
AND Document like '%limited%'
这是工作中的一个简化示例:SQLFiddle
编辑:
鉴于您提供的示例数据,这是我建议的解决方案:
WITH myCte AS (
SELECT
p.Last,
p.First,
p.person_id,
i.Document,
i.Expiration_date,
i.Updated_Date,
i.Historical,
f.Current_status,
i.State as DocumentState,
COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
FROM dbo.PersonDoc_ID_Numbers i
JOIN dbo.Person p ON p.person_id = i.person_id
JOIN person_facilities f ON p.person_id = f.person_id
WHERE
(Document like '%limited%' AND i.State like '%NY%' AND ((i.Expiration_date > getdate()) OR (i.Expiration_date is null))) or
(Document like '%NY%' AND i.State like '%NY%' AND ((i.Expiration_date > getdate()) OR (i.Expiration_date is null)))
AND f.current_status in ('Active')
AND i.Historical != 1
)
SELECT Last
,First
,person_id
,Document
,Expiration_date
,Updated_Date
,Historical
,Current_status
,DocumentState
FROM myCte
WHERE noOfRows = 1
AND Document like '%limited%'
这是一个使用所提供数据的新示例:SQLFiddle
您可以试试下面的查询。
WITH cte AS (
SELECT p.Last_Name
, p.First_Name
, p.Middle_Initial
, p.person_id
, i.Document
, i.Expiration_date
, i.Updated_Date
FROM dbo.PersonDoc_ID_Numbers i
JOIN "DB"."dbo"."People" p ON p.person_id = i.person_id
JOIN person_facilities f ON p.person_id = f.person_id
WHERE /*Document LIKE '%limited%'
AND i.State LIKE '%NY%'
AND*/ (i.Expiration_date > GETDATE() OR i.Expiration_date IS NULL)
AND f.current_status IN ('Active')
AND i.Historical != 1
)
SELECT *
FROM cte c
WHERE Document LIKE '%limited%' AND i.State LIKE '%NY%'
AND NOT EXISTS (
SELECT 1
FROM cte
WHERE person_id = p.person_id AND Document NOT LIKE '%limited%' AND i.State LIKE '%NY%'
)
ORDER BY Last_Name
我正在尝试组合一个查询,这样我就可以在我们的数据库中找到既有 NY permit/license 也有有限 permit/license 的人,但是这些行是单独的行询问。我只想要那些没有纽约州驾照的,那里是有限制的。
这是我目前拥有的:
p.Last_Name
,p.First_Name
,p.Middle_Initial
,p.person_id
,i.Document
,i.Expiration_date
,i.Updated_Date
--,i.IssueDate
--,i.Historical
--,i.Comments
--,f.Current_status
,i.State
from dbo.PersonDoc_ID_Numbers i
inner join "DB"."dbo"."People" p on p.person_id = i.person_id
inner join person_facilities f on p.person_id = f.person_id
where
(Document like '%limited%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null))) or
(Document like '%NY%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null)))
and f.current_status in ('Active')
and i.Historical != 1
order by p.Last_Name
所以这 return 对某些人来说是这样的,但我不想要拥有纽约执照的人以及有限的人;我只想要没有纽约牌照的限量版:
Last_Name First_Name Middle_Initial person_id Document Expiration_date Updated_Date
GG FF L. 123 Limited Permit 2019-09-23 2018-10-04 456
GG FF L. 123 NY State License NULL 2018-11-13
Smith Tony L. 456 Limited Permit 2019-09-23 2018-10-04 456
Snoopy Dog L. 789 NY State License NULL 2018-11-13
所以对于 FF GG,我对她的名字被 returned 不感兴趣,因为她有任何执照,而且是有限的。我只想要有限的。但我希望 return Tony Smith 就是这样。
*Update as requested:
dbo.PersonDoc_ID_Numbers
person_id Expiration_date State license_NO Updated_Date Historical Document
1 2019-9-22 NY 2 2018-10-04 0 Limited Perm *
1 null NY no 2019-4-17 0 NY State
2 null NY 3 2011-06-30 0 Limited Lic
2 null NY 4 2011-06-14 0 NY State
3 2018-5-04 NY 5 2018-05-01 0 Limited Perm*
4 2019-08-29 NY 6 2018-01-12 0 Limited Lic *
5 null null 7 2016-4-20 0 Jujufication
5 null NY 8 2018-4-05 0 NY State
6 2016-07-15 OH 9 2018-01-09 0 Snoopyism
dbo.Person_Facilities
person_id Current_status
1 Active
2 Active
3 Active
4 Active
5 Active
6 Active
dbo.Person
person_id First Last
1 GG FF
2 MM PP
3 Tony Smith
4 Snoopy Dog
5 Sarah Gd
6 Bethany Yoda
我在 id table 中的那些旁边放了一个 *,它们应该在最后一组。请注意,事实证明 FF GG 没有执照号码,因此她需要在最后一组。
假设您当前的查询一切正常,您可以使用 COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
来确定查询将生成多少行,然后 select
只有单行的条目以及沿着这些行的查询:
WITH myCte AS (
SELECT
p.Last_Name
,p.First_Name
,p.Middle_Initial
,p.person_id
,i.Document
,i.Expiration_date
,i.Updated_Date
,i.IssueDate
,i.Historical
,i.Comments
,f.Current_status
,i.State as DocumentState
,COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
from dbo.PersonDoc_ID_Numbers i
inner join "DB"."dbo"."People" p on p.person_id = i.person_id
left join person_facilities f on p.person_id = f.person_id
where
(Document like '%limited%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null))) or
(Document like '%NY%' and i.State like '%NY%' and ((i.Expiration_date > getdate()) or (i.Expiration_date is null)))
and f.current_status in ('Active')
and i.Historical != 1
)
SELECT Last_Name
,First_Name
,Middle_Initial
,person_id
,Document
,Expiration_date
,Updated_Date
,IssueDate
,Historical
,Comments
,Current_status
,DocumentState
FROM myCte
WHERE noOfRows = 1
AND Document like '%limited%'
这是工作中的一个简化示例:SQLFiddle
编辑:
鉴于您提供的示例数据,这是我建议的解决方案:
WITH myCte AS (
SELECT
p.Last,
p.First,
p.person_id,
i.Document,
i.Expiration_date,
i.Updated_Date,
i.Historical,
f.Current_status,
i.State as DocumentState,
COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows
FROM dbo.PersonDoc_ID_Numbers i
JOIN dbo.Person p ON p.person_id = i.person_id
JOIN person_facilities f ON p.person_id = f.person_id
WHERE
(Document like '%limited%' AND i.State like '%NY%' AND ((i.Expiration_date > getdate()) OR (i.Expiration_date is null))) or
(Document like '%NY%' AND i.State like '%NY%' AND ((i.Expiration_date > getdate()) OR (i.Expiration_date is null)))
AND f.current_status in ('Active')
AND i.Historical != 1
)
SELECT Last
,First
,person_id
,Document
,Expiration_date
,Updated_Date
,Historical
,Current_status
,DocumentState
FROM myCte
WHERE noOfRows = 1
AND Document like '%limited%'
这是一个使用所提供数据的新示例:SQLFiddle
您可以试试下面的查询。
WITH cte AS (
SELECT p.Last_Name
, p.First_Name
, p.Middle_Initial
, p.person_id
, i.Document
, i.Expiration_date
, i.Updated_Date
FROM dbo.PersonDoc_ID_Numbers i
JOIN "DB"."dbo"."People" p ON p.person_id = i.person_id
JOIN person_facilities f ON p.person_id = f.person_id
WHERE /*Document LIKE '%limited%'
AND i.State LIKE '%NY%'
AND*/ (i.Expiration_date > GETDATE() OR i.Expiration_date IS NULL)
AND f.current_status IN ('Active')
AND i.Historical != 1
)
SELECT *
FROM cte c
WHERE Document LIKE '%limited%' AND i.State LIKE '%NY%'
AND NOT EXISTS (
SELECT 1
FROM cte
WHERE person_id = p.person_id AND Document NOT LIKE '%limited%' AND i.State LIKE '%NY%'
)
ORDER BY Last_Name