TSQL:条件查询问题

时间:2016-11-07 19:58:10

标签: sql-server tsql conditional

我需要创建一个标志来标识符合以下条件的所有Room_IDs

  • a" Qc - " Status位于一个Hotel_ID内。
  • " Qc - " Status有一个相应的非" Qc - " Status(例如 ' QC-占据' &安培; '所占据'。)
  • " Qc - " Status必须要比Room_IDStatus 非" Qc - " Status。 (例如Room_ID =' qc-occupied'有Status = 1而Room_ID ='被占用'有 **Hotel_ID Room_Id Status** 1 1 vacant 1 2 qc-occupied 1 3 vacant 2 1 occupied 2 2 qc-vacant 2 3 vacant 3 1 qc-vacant 4 1 vacant 4 2 occupied 4 3 qc-vacant 5 1 vacant = 5)

这是一个简化的表格(tableX)我用作例子:

 **Hotel_ID  Room_Id     Status         flag**
      1         1        vacant          0
      1         2        qc-occupied     0
      1         3        vacant          0 
      2         1        occupied        0
      2         2        qc-vacant       1
      2         3        vacant          1
      3         1        qc-vacant       0
      4         1        vacant          0
      4         2        occupied        0
      4         3        qc-vacant       0
      5         1        vacant          0

我需要以下结果:

import groovyx.net.http.RESTClient
import groovyx.net.http.HttpResponseException
import org.apache.http.conn.HttpHostConnectException


 def query = '**items.find({"repo": "xxx-repo-for-poc","created_by" :  "xxx","name" :{"$match": "*.nupkg"})**' // replace this with your AQL query
    def artifactoryURL = 'http://Servername:8081/artifactory/' // replace this with Artifactory server
    def restClient = new RESTClient(artifactoryURL)
    restClient.setHeaders(['Authorization': 'Basic ' + "admin:password".getBytes('iso-8859-1').encodeBase64()]) //replace the 'admin:password' with your own credentials
    def dryRun = true //set the value to false if you want the script to actually delete the artifacts

    def itemsToDelete = this.&getAqlQueryResult(restClient, query)
    if (itemsToDelete != null && itemsToDelete.size() > 0) {
         this.&delete(restClient, itemsToDelete, dryRun)
    } else {
        println('NOTHING TO DELETE')
    }

    /**
     * Send the AQL to Artifactory and collect the response.
     */
    public List getAqlQueryResult(RESTClient restClient, String query) {
        def response
        try {
            response = restClient.post(path: 'api/search/aql',
                    body: query,
                    requestContentType: 'text/plain'
            )
        } catch (Exception e) {
            println(e.message)
        }
        if (response != null && response.getData()) {
            def results = [];
            response.getData().results.each {
                results.add(constructPath(it))
            }
            return results;
        } else return null
    }

    /**
     * Construct the full path form the returned items.
     * If the path is '.' (file is on the root) we ignores it and construct the full path from the repo and the file name only
     */
    public constructPath(groovy.json.internal.LazyMap item) {
        if (item.path.toString().equals(".")) {
            return item.repo + "/" + item.name
        }
        return item.repo + "/" + item.path + "/" + item.name
    }

    /**
     * Send DELETE request to Artifactory for each one of the returned items
     */
    public delete(RESTClient restClient, List itemsToDelete, def dryRun) {
        dryMessage = (dryRun) ? "*** This is a dry run ***" : "";
        itemsToDelete.each {
            println("Trying to delete artifact: '$it'. $dryMessage")
            try {
                if (!dryRun) {
                    restClient.delete(path: it)
                }
                println("Artifact '$it' has been successfully deleted. $dryMessage")
            } catch (HttpResponseException e) {
                println("Cannot delete artifact '$it': $e.message" +
                        ", $e.statusCode")
            } catch (HttpHostConnectException e) {
                println("Cannot delete artifact '$it': $e.message")
            }
        }
    }

提前谢谢!

1 个答案:

答案 0 :(得分:1)

这是将需求字面翻译成相当不优雅的代码。它肯定可以改进,例如通过删除您的第一个要求(“qc-”存在。),因为它隐含在其他两个要求中。第二个要求隐含在第三个要求中,允许另一个改进。

-- Sample data.
declare @TableX as Table ( Hotel_Id Int, Room_Id Int, Stat VarChar(16) );
insert into @TableX ( Hotel_Id, Room_Id, Stat ) values
  ( 1, 1, 'vacant' ), ( 1, 2, 'qc-occupied' ), ( 1, 3, 'vacant' ), 
  ( 2, 1, 'occupied' ), ( 2, 2, 'qc-vacant' ), ( 2, 3, 'vacant' ), 
  ( 3, 1, 'qc-vacant' ),
  ( 4, 1, 'vacant' ), ( 4, 2, 'occupied' ), ( 4, 3, 'qc-vacant' ), 
  ( 5, 1, 'vacant' );
select * from @TableX;

-- Literal translation of requirements.
declare @False as Bit = 0, @True as Bit = 1;
select Hotel_Id, Room_Id, Stat,
  QC_In_Hotel, QC_And_NonQC_In_Hotel, QC_Precedes_NonQC_In_Hotel,
  case when QC_In_Hotel = @True and QC_And_NonQC_In_Hotel = @True and
    QC_Precedes_NonQC_In_Hotel = @True then @True else @False end as Flag
  from (
    select Hotel_Id, Room_Id, Stat,
      -- Req: a "Qc-" Status is present within one Hotel_ID.
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and I.Stat like 'qc-%' )
        then @True else @False end as QC_In_Hotel,
      -- Req: the "Qc-" Status has a corresponding non "Qc-" Status (e.g. 'qc-occupied' & 'occupied').
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and
          ( ( I.Stat like 'qc-' + O.Stat ) or ( O.Stat like 'qc-' + I.Stat ) ) )
        then @True else @False end as QC_And_NonQC_In_Hotel,
      -- Req: the "Qc-" Status has to have a to have a smaller Room_ID than the non "Qc-" Status.
      case when exists ( select 42 from @TableX as I
        where I.Hotel_Id = O.Hotel_Id and
          ( ( I.Room_Id < O.Room_Id and I.Stat like 'qc-' + O.Stat ) or
            ( O.Room_Id < I.Room_Id and O.Stat like 'qc-' + I.Stat ) ) )
        then @True else @False end as QC_Precedes_NonQC_In_Hotel
      from @TableX as O ) as PH
  order by Hotel_Id, Room_Id;