计算SQL子查询中的记录

时间:2017-11-16 20:33:03

标签: sql sql-server-2008 sql-server-2012

我对子查询有困难。用简单的英语我试图从QCUsers表中选择一个来自QCTier1_Assignments表的记录少于20条的随机用户ID。问题是我的查询只是挑选符合内部查询条件的用户,当我需要从QCUsers表中挑选任何用户时,即使用户在QCTier1_Assignments表中根本没有任何记录。我需要这样的东西

AND(Sub.QCCount< 20 OR Sub.QCCount = 0)

DECLARE @ReviewPeriodMonth varchar(10) = '10'
DECLARE @ReviewPeriodYear varchar(10) = '2015'

SELECT TOP 1
E1.UserID
,Sub.QCCount --Drawn from the subquery
FROM QCUsers E1
JOIN (SELECT 
  QCA.UserID, 
  COUNT(*) AS QCCount
  FROM QCTier1_Assignments QCA 
  WHERE QCA.ReviewPeriodMonth = @ReviewPeriodMonth
  AND QCA.ReviewPeriodYear = @ReviewPeriodYear
  GROUP BY QCA.UserID
  ) Sub
 ON E1.UserID = Sub.UserID
 WHERE Active = 1
  AND Grade = 12
  AND Sub.QCCount < 20
 ORDER BY NEWID()

我也试过这种方式没有运气

DECLARE @ReviewPeriodMonth varchar(10) = '10'
DECLARE @ReviewPeriodYear varchar(10) = '2015'

SELECT TOP 1
E1.UserID
,Sub.QCCount --Drawn from the subquery
FROM QCUsers E1
RIGHT JOIN (SELECT 
  QCA.UserID,
  ReviewPeriodMonth,
  ReviewPeriodYear, 
  COUNT(*) AS QCCount
  FROM QCTier1_Assignments QCA       
  GROUP BY 
    QCA.UserID,
    ReviewPeriodMonth,
    ReviewPeriodYear
  ) Sub
ON E1.UserID = Sub.UserID
WHERE Active = 1
  AND Grade = 12
  AND Sub.QCCount < 20
  AND Sub.ReviewPeriodMonth = @ReviewPeriodMonth
  AND Sub.ReviewPeriodYear = @ReviewPeriodYear
ORDER BY NEWID()

3 个答案:

答案 0 :(得分:2)

尝试使用您的第二个查询,但更改WHERE子句以使用COALESCE(Sub.QCCount, 0) instead of just Sub.QCCount`

如果子查询没有返回任何行,那么您的RIGHT JOIN至少仍然会获得该行,但QCCount将为NULL,与其他任何内容相比都会导致&# 34;假&#34;有效。

此外,您应该查看HAVING子句。它可能允许您在没有子查询的情况下执行此操作。

以下是HAVING子句的示例。如果它没有给出正确的结果,请告诉我,因为我无法测试。

DECLARE
    @ReviewPeriodMonth VARCHAR(10) = '10'
    @ReviewPeriodYear  VARCHAR(10) = '2015'

SELECT TOP 1
    E1.UserID,
    COUNT(QCA.UserID) AS QCCount
FROM
    QCUsers E1
LEFT OUTER JOIN QCTier1_Assignments QCA ON
    QCA.UserID = E1.UserID AND
    QCA.ReviewPeriodMonth = @ReviewPeriodMonth AND
    QCA.ReviewPeriodYear = @ReviewPeriodYear
WHERE
    E1.Active = 1 AND
    Grade = 12 AND
HAVING
    COUNT(*) < 20
ORDER BY
    NEWID()

答案 1 :(得分:0)

您应该使用LEFT JOIN代替JOIN(INNER JOIN),并且最好根据您的习惯将谓词放到外部查询中,但我建议采用以下方式:

SELECT TOP1 ABC.UserID,ABC.QCCount
FROM
(
    SELECT E1.UserID, COUNT(*) as QCCount
    FROM QCUsers as E1
    LEFT JOIN QCTier1_Assignments as QCA 
    ON QCA.UserID = E1.UserID
    WHERE QCA.ReviewPeriodMonth = @ReviewPeriodMonth
    AND QCA.ReviewPeriodYear = @ReviewPeriodYear
    AND Active = 1
    AND Grade = 12
    GROUP BY E1.UserID 
 ) as ABC
WHERE ABC.QCCount <20
ORDER BY NEWID()

答案 2 :(得分:0)

我能够通过这里的一系列回复来解决这个问题

DECLARE @ReviewPeriodMonth varchar(10) = '10'
DECLARE @ReviewPeriodYear varchar(10) = '2015'

SELECT TOP 1 
  QCUsers.UserID, 
  COUNT(QCTier1_Assignments.ReviewID) AS ReviewCount
FROM         
QCTier1_Assignments RIGHT OUTER JOIN
QCUsers ON QCTier1_Assignments.UserID = QCUsers.UserID
WHERE     
QCUsers.Active = 1
AND QCUsers.Grade = '12'
AND (ReviewPeriodMonth = @ReviewPeriodMonth OR ReviewPeriodMonth IS NULL)
AND (ReviewPeriodYear = @ReviewPeriodYear OR ReviewPeriodYear IS NULL)
GROUP BY 
QCUsers.UserID
HAVING      
(COALESCE(COUNT(QCTier1_Assignments.ReviewID),0) < 4)
ORDER BY NEWID()