【问题标题】:Stored Procedure with join returning multiple records连接返回多条记录的存储过程
【发布时间】:2014-04-08 08:26:24
【问题描述】:

我有以下存储过程:

ALTER PROCEDURE [dbo].[stp_RandomisationResultCount]
    @noOfRows INT,
    @subcouncil INT,
    @wards VARCHAR(MAX) = NULL,
    @suburbs VARCHAR(MAX) = NULL,
    @courts VARCHAR(MAX) = NULL,
    @skills VARCHAR(MAX) = NULL,
    @isDisabled VARCHAR(1) = NULL,
    @hasQualification VARCHAR(1) = NULL,
    @gender VARCHAR(1) = NULL,
    @age INT = NULL
AS
BEGIN
    SELECT  
        COUNT(tblJobSeekerDetails.JobSeeker_ID) resultCount
    FROM 
        tblJobSeekerDetails 
    LEFT JOIN 
        tbl_lnk_JobSeeker_OtherSkills ON tblJobSeekerDetails.JobSeeker_ID = tbl_lnk_JobSeeker_OtherSkills.JobSeeker_ID 
    LEFT JOIN 
        tblOtherSkills ON tbl_lnk_JobSeeker_OtherSkills.OtherSkillsID = tblOtherSkills.OtherSkillsID 
    /*LEFT JOIN tblJobSeekerEmploymentHistory
    ON tblJobSeekerDetails.JobSeeker_ID = tblJobSeekerEmploymentHistory.JobSeekerID*/
    WHERE 
        (tblJobSeekerDetails.SubCouncilID = @subcouncil)
        AND ((WardID IN (SELECT s.Item FROM ufn_SplitIntArray(@wards, ',') s)) OR (@wards IS NULL))
        AND ((Suburb IN (SELECT s.Item FROM ufn_SplitIntArray(@suburbs, ',') s)) OR (@suburbs IS NULL))
        AND ((RoadType IN (SELECT s.Item FROM ufn_SplitIntArray(@courts, ',') s)) OR (@courts IS NULL))
        AND ((tblOtherSkills.OtherSkillsID in (SELECT s.Item FROM ufn_SplitIntArray(@skills, ',') s)) OR (@skills IS NULL))
        AND ((Disability = @isDisabled) OR (@isDisabled IS NULL))
        AND ((HasTertiaryQualification = @hasQualification) OR (@hasQualification IS NULL))
        AND ((Gender = @gender) OR (@gender IS NULL))
        AND ((ISNUMERIC(IdentityNumber) = 1 AND 
              IdentityNumber NOT LIKE '%.%' AND 
              DATEPART(YEAR, GETDATE()) - (CONVERT(INT, '19' + SUBSTRING(IdentityNumber, 1, 2), 100)) = @age) OR (@age IS NULL))
        AND (TypeID = 1)--Jobseekers only
        AND (tblJobSeekerDetails.IsExcludedFromRandomisation <> 1 OR tblJobSeekerDetails.IsExcludedFromRandomisation IS NULL)--Explicitly excluded jobseekers
        AND (tblJobSeekerDetails.JobSeeker_ID not in (SELECT DISTINCT tj.JobSeeker_ID --Exclude Jobseekers as per stipulated exclusion periods
                                                      FROM tblJobSeekerDetails tj INNER JOIN tblJobSeekerEmploymentHistory wh
                                                      ON tj.JobSeeker_ID = wh.JobSeekerID
                                                      WHERE ((DATEDIFF(DAY, wh.DateOfEmploymentFrom, wh.DateOfEmploymentTo) <= 14 AND DATEDIFF(MONTH, wh.DateOfEmploymentTo, GETDATE()) <= 3 ))
                                                      OR
                                                      ((DATEDIFF(DAY, wh.DateOfEmploymentFrom, wh.DateOfEmploymentTo) > 14 AND DATEDIFF(MONTH, wh.DateOfEmploymentTo, GETDATE()) <= 6))
                                                      OR
                                                      (GETDATE() BETWEEN wh.DateOfEmploymentFrom AND wh.DateOfEmploymentTo)
                                                      OR (wh.DateOfEmploymentFrom > GETDATE() OR wh.DateOfEmploymentTo > GETDATE())
                                                      GROUP BY tj.JobSeeker_ID))
        AND (tblJobSeekerDetails.JobSeeker_ID NOT IN (SELECT DISTINCT te.JobSeeker_ID -- Exclude jobseekers that were recently availed to a project
                                                      FROM tblJobSeekerDetails te INNER JOIN tbl_RandomisedJobseeker rj
                                                      ON te.JobSeeker_ID = rj.JobseekerID
                                                      WHERE (GETDATE() < rj.ExcludedTo)
                                                      GROUP BY te.JobSeeker_ID))
END

此存储过程为拥有多个“其他技能”的求职者返回多条记录。我需要修改它,使它只返回一个。我认为这是由于加入。然而,我不能只返回第一个“OtherSkill”。我需要给定求职者的所有技能,以便我可以将其与收到的标准进行比较。

(我刚开始考虑使用表变量的可能性。有时写一个问题真的很有帮助:))

【问题讨论】:

  • 如何让所有技能连续返回?
  • @Szymon:不完全确定。我正在考虑将它们全部放入一个表变量中并在存储过程中使用它。问题是,这个变量中会有很多记录。至少超过 500k
  • 而且,有了这个,我不知道如何只比较给定求职者的技能

标签: sql stored-procedures sql-server-2012


【解决方案1】:

我通过使用WITH 子句从求职者表中加载我需要过滤以进行计数的所有数据来解决这个问题。我也对这个WITH中的技能进行过滤:

ALTER PROCEDURE [dbo].[stp_RandomisationResultCount]
    @noOfRows INT,
    @subcouncil INT,
    @wards VARCHAR(MAX) = NULL,
    @suburbs VARCHAR(MAX) = NULL,
    @courts VARCHAR(MAX) = NULL,
    @skills VARCHAR(MAX) = NULL,
    @isDisabled VARCHAR(1) = NULL,
    @hasQualification VARCHAR(1) = NULL,
    @gender VARCHAR(1) = NULL,
    @age INT = NULL
AS
BEGIN
    WITH JobSeekerDetails AS
    (
        SELECT DISTINCT jsd.JobSeeker_ID,
                        jsd.SubCouncilID,
                        jsd.WardID,
                        jsd.Suburb,
                        jsd.RoadType,
                        jsd.Disability,
                        jsd.HasTertiaryQualification,
                        jsd.Gender,
                        jsd.IdentityNumber,
                        jsd.TypeID,
                        jsd.IsExcludedFromRandomisation
        FROM dbo.tblJobSeekerDetails jsd
        LEFT JOIN tbl_lnk_JobSeeker_OtherSkills jos
        ON jsd.JobSeeker_ID = jsd.JobSeeker_ID
        LEFT JOIN tblOtherSkills os
        ON jos.OtherSkillsID = os.OtherSkillsID
        WHERE ((os.OtherSkillsID in (SELECT s.Item FROM ufn_SplitIntArray(@skills, ',') s)) OR (@skills IS NULL))
    )

    SELECT COUNT(jsd.JobSeeker_ID) resultCount
    FROM tblJobSeekerDetails jsd
    INNER JOIN JobSeekerDetails
    ON jsd.JobSeeker_ID = JobSeekerDetails.JobSeeker_ID
    WHERE (jsd.SubCouncilID = @subcouncil)
        AND ((jsd.WardID IN (SELECT s.Item FROM ufn_SplitIntArray(@wards, ',') s)) OR (@wards IS NULL))
        AND ((jsd.Suburb IN (SELECT s.Item FROM ufn_SplitIntArray(@suburbs, ',') s)) OR (@suburbs IS NULL))
        AND ((jsd.RoadType IN (SELECT s.Item FROM ufn_SplitIntArray(@courts, ',') s)) OR (@courts IS NULL))
        AND ((jsd.Disability = @isDisabled) OR (@isDisabled IS NULL))
        AND ((jsd.HasTertiaryQualification = @hasQualification) OR (@hasQualification IS NULL))
        AND ((jsd.Gender = @gender) OR (@gender IS NULL))
        AND ((ISNUMERIC(jsd.IdentityNumber) = 1 AND 
              jsd.IdentityNumber NOT LIKE '%.%' AND 
              DATEPART(YEAR, GETDATE()) - (CONVERT(INT, '19' + SUBSTRING(jsd.IdentityNumber, 1, 2), 100)) = @age) OR (@age IS NULL))
        AND (jsd.TypeID = 1)--Jobseekers only
        AND (jsd.IsExcludedFromRandomisation <> 1 OR jsd.IsExcludedFromRandomisation IS NULL)--Explicitly excluded jobseekers
        AND (jsd.JobSeeker_ID not in (SELECT DISTINCT tj.JobSeeker_ID --Exclude Jobseekers as per stipulated exclusion period
                                      FROM tblJobSeekerDetails tj
                                      INNER JOIN tblJobSeekerEmploymentHistory wh
                                      ON tj.JobSeeker_ID = wh.JobSeekerID
                                      WHERE ((DATEDIFF(DAY, wh.DateOfEmploymentFrom, wh.DateOfEmploymentTo) <= 14 AND DATEDIFF(MONTH, wh.DateOfEmploymentTo, GETDATE()) <= 3 ))
                                      OR
                                      ((DATEDIFF(DAY, wh.DateOfEmploymentFrom, wh.DateOfEmploymentTo) > 14 AND DATEDIFF(MONTH, wh.DateOfEmploymentTo, GETDATE()) <= 6))
                                      OR
                                      (GETDATE() BETWEEN wh.DateOfEmploymentFrom AND wh.DateOfEmploymentTo)
                                      OR (wh.DateOfEmploymentFrom > GETDATE() OR wh.DateOfEmploymentTo > GETDATE())
                                      GROUP BY tj.JobSeeker_ID))
        AND (jsd.JobSeeker_ID NOT IN (SELECT DISTINCT te.JobSeeker_ID -- Exclude jobseekers that were recently availed to a project
                                      FROM tblJobSeekerDetails te INNER JOIN tbl_RandomisedJobseeker rj
                                      ON te.JobSeeker_ID = rj.JobseekerID
                                      WHERE (GETDATE() < rj.ExcludedTo)
                                      GROUP BY te.JobSeeker_ID))
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 2019-04-20
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多