0

I have 2 tables, Requests and Responses

Requests:

RequestId  UserId  InsertDate
1           1       5/4/2013
2           2       6/4/2012
.           .          .
.           .          .

Responses:

Responseid  Requestid(FK)  ResponseCode  
    1           1              A   
    2           1              V
    3           1              M   
    4           2              A
    5           2              S   
    6           2              D
    .           .              .
    .           .              .

Request is considered as "Passed" if response codes A and D are received (like request with id 2 in my example). I want to write a sql queries that will return 3 things:

  • number of "Passed" requests
  • RequestIDs of those requests that pass
  • RequestIDs of those requests that didn't pass

I wrote something but I don't like it and I suppose there is better way. My query is:

SELECT COUNT(*) 
FROM
(
  SELECT count(*) as c, req.RequestID
  FROM Responses res inner join Requests req 
  on req.RequestID = res.RequestID
  where 
      res.ResponseCode = 'A' or
      res.ResponseCode = 'D' 

  group by req.RequestID
)cc

where c = 2

Thanks in advance.

4

4 に答える 4

2

応答コードAとDの両方を持つリクエストIDを返すには、次の方法を使用HAVINGCOUNTます。

SELECT res.requestId
FROM Responses res inner join Requests req 
  on req.RequestID = res.requestid
WHERE res.ResponseCode IN ('A','D')
GROUP BY res.requestId
HAVING COUNT(DISTINCT res.ResponseCode) = 2

SQLフィドルデモ

于 2013-02-21T21:20:18.953 に答える
1

これを行う別の根本的に異なる方法を考えることはできません(つまり、同等のサブクエリまたはCTEがない場合)。ただし、「A」と「D」の値を別々に明示的にテストします。

SELECT COUNT(*) as c, req.RequestID
FROM Responses res inner join
     Requests req 
     on req.RequestID = res.EquifaxIDCompareRequestID
where res.ResponseCode in ('A', 'D')
group by EquifaxIDCompareRequestID
having SUM(case when res.ResponseCode = 'D' then 1 else 0 end) > 0 and
       SUM(case when res.ResponseCode = 'A' then 1 else 0 end)

この句は、「A」と「D」の両方が結果セットに含まれていることを確認することを除いてhaving、外部句と似ています。where

結合またはサブクエリを使用する別のアプローチがあります。このようなもの:

select EquifaxIDCompareRequestID
from Requests req
where EquifaxIDCompareRequestID in (select RequestID from responses where ResponseCode = 'A') and
      EquifaxIDCompareRequestID in (select RequestID from responses where ResponseCode = 'D') 
于 2013-02-21T21:19:24.013 に答える
1

合格

SELECT r1.RequestID
FROM Responses R1
JOIN Responses R2
  on R2.RequestID = R1.RequestID
 and R1.ResponseCode = 'A' 
 and R2.ResponseCode = 'D'
compute count(r1.RequestID)

(計算構文では肯定的ではありません)

通らない

SELECT distinct (r1.RequestID)
FROM Responses R1
FULL OUTTER JOIN Responses R2
  on R2.RequestID = R1.RequestID
 and R1.ResponseCode = 'A' 
 and R2.ResponseCode = 'D'
WHERE R2.RequestID is null 
   OR R1.RequestID is null

合格

SELECT r1.RequestID
FROM  Responses R1
WHERE R1.ResponseCode = 'A' 
INTERSECT 
SELECT r1.RequestID
FROM  Responses R1
WHERE R1.ResponseCode = 'D'

通らない

SELECT r1.RequestID
FROM  Responses R1
EXCEPT
SELECT r1.RequestID
FROM  Responses R1
WHERE R1.ResponseCode = 'D'
   OR R1.ResponseCode = 'A' 
于 2013-02-21T21:36:29.473 に答える
1

以下は、各 requestId について、それが成功したか失敗したか、およびそれが含まれるグループ内の総数 (成功または失敗) を示します (つまり、成功した場合は、成功した要求の総数、失敗した場合は、総数失敗した要求の数)。

with myCTE as
(
    select rq.requestId, case when rA.responseCode='A' and rD.responseCode='D' then 1 else 0 end as passed
    from dbo.Requests as rq
    outer apply
    (
        select top (1) re.responseCode
        from dbo.Responses as re
        where re.requestId=rq.requestId
            and re.responseCode='A'
    ) as rA
    outer apply
    (
        select top (1) re.responseCode
        from dbo.Responses as re
        where re.requestId=rq.requestId
            and re.responseCode='D'
    ) as rD
)
select *, count(*) over (partition by m.passed) as totalNumInGroup
from myCTE as m
于 2013-02-21T22:52:28.143 に答える