比较两个查询?

时间:2018-10-18 22:07:04

标签: sql sql-server tsql

我需要找到在一个程序(MMU)中注册的客户,然后在2018年1月1日至2018年8月15日之间切换到另一个客户(PCHP)。我有以下查询,该查询返回在两个日期之间具有StartDate的(MMU)程序中注册的客户端。这很好用,但是如何比较它们是否切换了程序?目前,我有此查询。

 SELECT c.ULink,
  c.ClientID,
  c.FirstName,
  c.LastName,
  s.LastName AS Staff_LastName,
  s.FirstName AS Staff_FirstName,
  cp1.Description,
  cp.StartDate,
  cp.EndDate
FROM Client c
LEFT JOIN Client_Program cp ON cp.ClientULink = c.ULink
LEFT JOIN Code_Program cp1 ON cp1.ULink = cp.ProgramULink
LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
WHERE cp.ProgramULink = 'MMU') 
  AND cp.ProgramStatusULink = 'Open' 
  AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15'

现在,我需要在ProgramULink ='PCHP'时使用相同的查询(但仅当它们在MMU中时)。希望有道理。不确定如何执行此查询的逻辑。

谢谢。

5 个答案:

答案 0 :(得分:1)

在哪里杀死左联接,您还有一个额外的

 SELECT c.ULink,
  c.ClientID,
  c.FirstName,
  c.LastName,
  s.LastName AS Staff_LastName,
  s.FirstName AS Staff_FirstName,
  cp1.Description,
  cp.StartDate,
  cp.EndDate
FROM Client c
INNER JOIN Client_Program cp ON cp.ClientULink = c.ULink
LEFT  JOIN Code_Program cp1  ON cp1.ULink = cp.ProgramULink
LEFT  JOIN Staff s           ON s.ULink = c.RecordCreatedBy
WHERE cp.ProgramULink = 'MMU' 
  AND cp.ProgramStatusULink = 'Open' 
  AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15' 
  AND EXISTS ( select 1 
               FROM Client c2
               INNER JOIN Client_Program cp2 
                  ON cp2.ClientULink = c.ULink 
                 AND cp2.ProgramULink = 'PCHP'   
                 AND c2.ClientID =  c.ClientID
             )                       

答案 1 :(得分:1)

为了使事情变得简单明了,我建议使用临时表存储初始结果:

IF OBJECT_ID ('TEMPDB..#MMU') IS NOT NULL DROP TABLE #MMU
SELECT c.ClientID
INTO #MMU
FROM Client c
LEFT JOIN Client_Program cp ON cp.ClientULink = c.ULink
LEFT JOIN Code_Program cp1 ON cp1.ULink = cp.ProgramULink
LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
WHERE cp.ProgramULink = 'MMU') 
  AND cp.ProgramStatusULink = 'Open' 
  AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15'


 SELECT c.ULink,
  c.ClientID,
  c.FirstName,
  c.LastName,
  s.LastName AS Staff_LastName,
  s.FirstName AS Staff_FirstName,
  cp1.Description,
  cp.StartDate,
  cp.EndDate
FROM Client c
LEFT JOIN Client_Program cp ON cp.ClientULink = c.ULink
LEFT JOIN Code_Program cp1 ON cp1.ULink = cp.ProgramULink
LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
WHERE cp.ProgramULink = 'PCHP') 
  AND cp.ProgramStatusULink = 'Open' 
  AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15'
  AND ClientID IN ( SELECT ClientID FROM #MMU WHERE ClientID IS NOT NULL )

根据您的经验水平,这可能比其他建议要容易一些。

答案 2 :(得分:0)

如果同时过滤两个程序,则可以使用GROUP BYHAVING查找具有多个程序的ClientID

SELECT c.ClientID
FROM Client c
LEFT JOIN Client_Program cp ON cp.ClientULink = c.ULink
LEFT JOIN Code_Program cp1 ON cp1.ULink = cp.ProgramULink
LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
WHERE cp.ProgramULink IN ('MMU','PCHP') 
  AND cp.ProgramStatusULink = 'Open' 
  AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15'
GROUP BY c.ClientID
 HAVING COUNT(DISTINCT cp.ProgramULink) > 1

您不能在上面包含程序特定的字段,如果要查看具有两个的程序的完整详细信息,可以改用类似的内容:

;with cte as ( SELECT COUNT(*) OVER(PARTITION BY c.ClientID) as ct
                      c.ULink,
                      c.ClientID,
                      c.FirstName,
                      c.LastName,
                      s.LastName AS Staff_LastName,
                      s.FirstName AS Staff_FirstName,
                      cp1.Description,
                      cp.StartDate,
                      cp.EndDate
               FROM Client c
               LEFT JOIN Client_Program cp ON cp.ClientULink = c.ULink
               LEFT JOIN Code_Program cp1 ON cp1.ULink = cp.ProgramULink
               LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
               WHERE cp.ProgramULink IN ('MMU','PCHP') 
                 AND cp.ProgramStatusULink = 'Open' 
                 AND cp.StartDate BETWEEN '2018-01-01' AND '2018-08-15'
              )
SELECT *
FROM cte
WHERE ct > 1
ORDER BY ct DESC,ClientID

这两个都假设ClientID是关键,如果没有,则可以根据需要向SELECTGROUP BYPARTITION BY添加其他字段。第二个查询还会返回某人在同一程序中有多个记录的实例。

答案 3 :(得分:0)

认为可以,但是同样,如果不查看示例数据,很难做到这一点。

<script>
  myObj = 
    {
        "$id":"1",
        "Description":"WA State",
        "Place":"WA",
        "Data":[
        {
            "$id":"2",
            "Description":"Years",
            "Indicators":[
            {
                "$id":"3",
                "Year":2017,
                "Points":22191,
                "Goal":"28000",
                "Description":"Year 2017"
            },
            {
                "$id":"4",
                "Year":2018,
                "Points":25994,
                "Goal":"28000",
                "Description":"Year 2018"
            }
            ]
        },
        {
            "$id":"5",
            "Description":"Local Goal",
            "Indicators":[
            {
                "$id":"6",
                "Year":2018,
                "Points":25994,
                "Goal":"28000",
                "Description":"Year 2018"
            }
            ]
        },
        {
            "$id":"7",
            "Description":"Remote Goal",
            "Indicators":[
            {
                "$id":"8",
                "Year":2018,
                "Points":55857,
                "Goal":"84000",
                "Description":"Year 2018"
            }
            ]
        }
        ]
    };
</script>

基本上,您正在使用两个子查询来生成MMU中的客户端列表和PCHP中的客户端列表,并查看两个客户端中都有哪些客户端。从那里开始,与其他表进行JOIN操作以获取剩余数据应该很简单。

答案 4 :(得分:0)

SELECT c.ULink,
  c.ClientID,
  c.FirstName,
  c.LastName,
  s.LastName AS Staff_LastName,
  s.FirstName AS Staff_FirstName,
  cp.Description,
  pchp.StartDate,
  pchp.EndDate
FROM Client c 
INNER JOIN Client_Program mmu ON mmu.ClientULink = c.ULink 
    AND mmu.ProgramULink = 'MMU' AND mmu.ProgramStatusULink = 'Open'
INNER JOIN Client_Program pchp ON pchp.ProgramULink = 'PCHP'
    AND pchp.ClientULink = mmu.ClientULink AND pchp.ProgramStatusULink = 'Open'
    AND pchp.StartDate BETWEEN '20180101' AND '20180815'
LEFT JOIN Code_Program cp ON cp.ULink = pchp.ProgramULink
LEFT JOIN Staff s ON s.ULink = c.RecordCreatedBy
WHERE mmu.StartDate < pchp.StartDate