简体   繁体   中英

How can I properly compose this sql subquery to values from another table instead of hard coding them?

Not even sure if I worded the question correctly, I have a huge sql server handicap, so this may be a simple thing I am not seeing. I have the following query:

select 
stu.SyStudentId,
stu.FirstName, 
stu.LastName, 
stu.StartDate,
enr.AdProgramVersionId,
enr.AdCatalogYearId,
enr.GPA as CumGPA,
case when (stu.DateLstMod > enr.DateLstMod) 
  then stu.DateLstMod 
  else enr.DateLstMod 
end as DateLstMod
from 
  SyStudent stu
  inner join adenroll enr on enr.systudentid = stu.systudentid
  inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
  inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
        where systa.category in ('E','A') 
        and stu.sycampusid = 6
        and 
        ( 
            enr.AdProgramVersionId is null 
            or 
            (enr.AdProgramVersionId = '52' and enr.AdCatalogYearId='3')
            or
            (enr.AdProgramVersionId='53' and enr.AdCatalogYearId='3')
            or
            (enr.AdProgramVersionId='50' and enr.AdCatalogYearId='3')
            or
            (enr.AdProgramVersionId='51' and enr.AdCatalogYearId='3')
            or
            (enr.AdProgramVersionId='52' and enr.AdCatalogYearId='4')
            or
            (enr.AdProgramVersionId='53' and enr.AdCatalogYearId='4')
            or
            (enr.AdProgramVersionId='50' and enr.AdCatalogYearId='4')
            or
            (enr.AdProgramVersionId='51' and enr.AdCatalogYearId='4')
            or
            (enr.AdProgramVersionId='54' and enr.AdCatalogYearId='4')
        )

The values in the nested 'and' clause can all be pulled from the database itself. The condition for the value is basically this:

Select adProgramVersionID
from AdEnroll
where AdCatalogYearId is not null

but if I try to put that in rather than the list of or clauses I get a different result set. Is there a way to accomplish what I need to do (replace the hard coded numbers with a retrieval of that number from the table)? Subqueries? Weird joins? Black magic?

This is the code that I am trying to replace with just a straight sql query:

var query = @"
        select 
          stu.SyStudentId,
          stu.FirstName, 
          stu.LastName, 
          stu.StartDate,
          enr.AdProgramVersionId,
          enr.AdCatalogYearId,
          enr.GPA as CumGPA,
          case when (stu.DateLstMod > enr.DateLstMod) 
            then stu.DateLstMod 
            else enr.DateLstMod 
          end as DateLstMod
        from 
          SyStudent stu
          inner join adenroll enr on enr.systudentid = stu.systudentid
          inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
          inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
        where systa.category in ('E','A') 
        and stu.sycampusid = 6 
        and 
        (
            enr.AdProgramVersionId in 
            ("
                + String.Join(",", dc.CatalogPrograms.Where(cp => cp.Catalog.CvAdCatalogYearId == null).Select(cp => cp.CvAdProgramVersionId)) + @"
            )
            or
            (";

            // get the students in program versions that use catalogs 

            var andClauses = new List<string>();
            foreach (var catProg in dc.CatalogPrograms.Where(cp => cp.Catalog.CvAdCatalogYearId != null))
                andClauses.Add("(enr.AdProgramVersionId=" + catProg.CvAdProgramVersionId + " and enr.AdCatalogYearId=" + catProg.Catalog.CvAdCatalogYearId + ")");

            query += string.Join("\n or", andClauses) + @"

            )
        )";

The reason I want to get rid of this code is I do not want to mix linq-to-sql in the new solution, I am using this as an import to a new database design altogether that will be using EF as the ORM.

You can incorporate the AdEnroll into your FROM clause and then simplify the WHERE as follows. My edits are in CAPS.

from 
  SyStudent stu
  inner join adenroll enr on enr.systudentid = stu.systudentid
  inner join syschoolstatus schsta on schsta.syschoolstatusid = enr.syschoolstatusid
  inner join SyStatus systa on systa.SyStatusId = schsta.SyStatusId
  LEFT OUTER JOIN ADENROLL AE ON ENR.ADPROGRAMVERSIONID = AE.ADPROGRAMVERSIONID
where systa.category in ('E','A') 
and stu.sycampusid = 6
and 
( 
    enr.AdProgramVersionId is null 
    OR 
    AE.ADCATALOGYEARID IS NOT NULL
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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