简体   繁体   English

如何找到具有两个特定许可证的人,单独的行,只有一个具有有限许可证的人

[英]How find people with two specific licenses, separate rows, only one with limited permit

I'm trying to put together a query so I can find people in our db that have both a NY permit/license and also a limited permit/license, but the rows are separate rows in the query. 我正在尝试将查询放在一起,以便我可以在我们的数据库中找到同时具有NY许可证/许可证以及有限许可证/许可证的人员,但这些行在查询中是单独的行。 I only want the ones without NYS license, where they are limited. 我只想要那些没有NYS许可证的人,他们是有限的。

This is what I have so far: 这是我到目前为止:

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

So that's returning like this for someone, but I don't want the ones with NY license as well as limited; 所以对于某人来说这样的回归,但我不希望那些有NY许可证的人也有限; I just want ones with limited without NY license: 我只想要那些没有NY许可证的人:

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 

So for FF GG, I wouldn't be interested in her name being returned because she has ny license, and the limited. 所以对于FF GG,我不会对她的名字被退回感兴趣,因为她有ny许可证,而且有限。 I only want ones with just limited. 我只想要有限的。 But I would expect it to return Tony Smith and that's it. 但我希望它能归还托尼史密斯,就是这样。

*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      

I put an * next to the ones in the id table where they are expected to be in the end set. 我在id表的旁边放了一个*,它们应该在最终集中。 Note that it turns out FF GG doesn't have a license number so she needs to be in the end set. 请注意,事实证明FF GG没有许可证编号,因此她需要在最终设置中。

Assuming your current query is all fine, you could use COUNT(*) OVER(PARTITION BY p.person_id) AS noOfRows to determine how many rows the query will generate, then select only the entries with a single row with a query along these lines: 假设您当前的查询都很好,您可以使用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%'

Here's a simplified example of this at work: SQLFiddle 这是一个简单的例子: SQLFiddle

EDIT: 编辑:

Given the sample data you have provided, here is my suggested solution: 根据您提供的示例数据,这是我建议的解决方案:

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

Here's a new example using the data provided: SQLFiddle 这是使用提供的数据的新示例: SQLFiddle

You can try the query below. 您可以尝试以下查询。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM