简体   繁体   中英

How to self join this SQL

I have one table in my Database that has column names: buildNumber , result , versionStatus . Now in my SQL statement I want to display the 'buildNumber' where the 'versionStatus' is old and the 'result' is pass and where the versionStatus is new and the result is 'fail '. So I want to display anything that has a result of fail today but had a result of pass last time. So if I have these records in the DB (column separated by --):

build2--pass--old
build2--fail--new

The SQL statement should only display "build2" because it passed with "old" but now 'failed' with new version.

I have tried:

select *
from CSAResults.dbo.Details
where result = 'pass'
and versionStatus = 'Old'
and versionStatus IN (select CSAResults.dbo.Details.versionStatus
                        from CSAResults.dbo.Details
                        where versionStatus = 'New'
                        and result = 'fail')

but nothing is returned.

Thanks

Your existing query should work if you change the IN condition to be:

and buildNumber IN (select CSAResults.dbo.Details.buildNumber

Alternatively, a better performing query might be:

Select buildNumber
from CSAResults.dbo.Details
group by buildNumber
having count(distinct case
                          when result = 'pass' and versionStatus = 'Old' then 1
                          when result = 'fail' and versionStatus = 'New' then 2
                      end) = 2

This query does a self-joins of Details table to get the result you want.

SELECT distinct new.buildNumber
FROM CSAResults.dbo.Details old
JOIN CSAResults.dbo.Details new ON old.buildNumber = new.buildNumber
WHERE old.result = 'pass'
  AND old.versionStatus = 'Old'
  AND new.result='fail'
  AND new.versionStatus='New'

I added the distinct in the select clause so you wouldn't get duplicate results if there were multiple old versions of the build that had passed

An alternative would be to use an INNER JOIN as so:

select t.* 
from CSAResults.dbo.Details t INNER JOIN (SELECT t2.buildNumber
                                    FROM CSAResults.dbo.Details t2
                                    WHERE t2.versionStatus = 'New'                         
                                    and t2.result = 'fail') t1
                              ON t.buildNumber = t1.buildNumber
where t.result = 'pass' 
and t.versionStatus = 'Old' 

Nothing returned? Hardly surprising: you're trying to assert

(VersionStatus='New') = (VersionStatus='Old')

Try something like this instead

select *
from CSAResults.dbo.Details
where result = 'pass'
and versionStatus = 'Old'
and buildNumber IN (select CSAResults.dbo.Details.buildNumber                           from CSAResults.dbo.Details
            where versionStatus = 'New'
            and result = 'fail')

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