【问题标题】:SQL Sorting: ORDER BY with parametersSQL 排序:带参数的 ORDER BY
【发布时间】:2014-07-09 13:35:34
【问题描述】:

执行此语句时遇到问题。

我在这里想要实现的是,我的结果将使用参数按条件排序。

例如,我想按升序对用户名进行排序,因此,在我的 Web 应用程序编码中,我有一个参数 @condition,当它读取“用户名”时,将执行下面的 sql 语句。

错误是:

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

Msg 206, Level 16, State 2, Line 1
Operand type clash: int is incompatible with date

出现了 6 次。

我不确定是否正确使用了 CASE。

我想要的结果是,当一个条件被调用并插入@condition 时,它应该对该特定条件的结果进行排序。

数据库中的属性是这样声明的:

C.joinDate - DATE
C.userName - VARCHAR(20)
C.firstName - VARCHAR(20)
C.lastName -  VARCHAR(15)
C.contact - CHAR(8)
C.dob - DATE
C.userStatus - VARCHAR(8)
C.totalPoints - INT
R.resID - VARCHAR(8)
P.orderID - VARCHAR(8)
D.orderID - VARCHAR(8)
CR.securityCode - VARCHAR(10)
C.loginAttempted - INT



SELECT C.joinDate, C.userName, (C.firstName+' '+C.lastName) AS Name, 
 C.contact, C.dob, C.userStatus, C.totalPoints,  COUNT(R.resID) AS Res,
 COUNT(P.orderID) AS PreOrd, COUNT(D.orderID) AS DelOrd, 
 COUNT(CR.securityCode) AS Redeem, C.loginAttempted  FROM Customer C
 full join Reservation R  ON C.userID = R.userID  full join PreOrder P
 ON R.resID = P.ResID  full join DeliveryOrder D ON D.userID = C.userID
 full join CustomerRedemption CR ON CR.userID = C.userID WHERE
 (C.firstName+' '+C.lastName) LIKE '%%' and c.userName LIKE '%%' and
 c.contact LIKE  '%%' and c.userStatus LIKE '%%' GROUP BY C.joinDate,
 C.userName, (C.firstName+' '+C.lastName), C.contact, C.dob, 
 C.userStatus, C.totalPoints, C.loginAttempted HAVING C.userName IS NOT
 NULL ORDER BY          CASE 'userName'
                WHEN 'joinDate' THEN joinDate
                WHEN 'userName' THEN userName
                WHEN 'Name' THEN (C.firstName+' '+C.lastName)
                WHEN 'dob' THEN dob
                WHEN 'userSatus' THEN userStatus
                WHEN 'totalPoints' THEN totalPoints
                WHEN 'totalPoints' THEN totalPoints
                WHEN 'Res' THEN COUNT(R.resID)
                WHEN 'PreOrd' THEN COUNT(P.orderID)
                WHEN 'DelOrd' THEN COUNT(D.orderID)
                WHEN 'Redeem' THEN COUNT(CR.securityCode)
                END

【问题讨论】:

  • 你用的是什么数据库?
  • 不管数据库如何,如果查询的结果要在数据库之外被某种类型的客户端使用,不要在数据库中排序。在客户端执行此操作要便宜得多。

标签: sql sorting sql-order-by case


【解决方案1】:

当您通过 case 语句排序时,case 的所有可能输出必须是相同的类型。你需要将你的 case 语句分解成多个 case 语句。

每个 case 语句都应该返回一个单一的类型和 NULL 用于 else 情况。您可以将所有这些案例合并为一个订单。

【讨论】:

    【解决方案2】:

    你可能想尝试这样的事情:

    CASE WHEN @condition = 'username' THEN username
         WHEN @condition ='joinDate' THEN joinDate
         WHEN @condition = 'userName' THEN userName
         WHEN @condition = 'Name' THEN (C.firstName+' '+C.lastName)
         WHEN @condition = 'dob' THEN dob
         WHEN @condition = 'userSatus' THEN userStatus
         WHEN @condition = 'totalPoints' THEN totalPoints
         WHEN @condition = 'totalPoints' THEN totalPoints
         WHEN @condition = 'Res' THEN COUNT(R.resID)
         WHEN @condition = 'PreOrd' THEN COUNT(P.orderID)
         WHEN @condition = 'DelOrd' THEN COUNT(D.orderID)
         WHEN @condition = 'Redeem' THEN COUNT(CR.securityCode)
         END
    

    或者如你所见,它也是正确的,但稍作修正:

    CASE @condition
         WHEN 'username' THEN username
         WHEN 'joinDate' THEN joinDate
         WHEN 'userName' THEN userName
         WHEN 'Name' THEN (C.firstName+' '+C.lastName)
         WHEN 'dob' THEN dob
         WHEN 'userSatus' THEN userStatus
         WHEN 'totalPoints' THEN totalPoints
         WHEN 'totalPoints' THEN totalPoints
         WHEN 'Res' THEN COUNT(R.resID)
         WHEN 'PreOrd' THEN COUNT(P.orderID)
         WHEN 'DelOrd' THEN COUNT(D.orderID)
         WHEN 'Redeem' THEN COUNT(CR.securityCode)
         END
    

    【讨论】:

      【解决方案3】:

      是的,您的问题在您的 CASE 声明中。首先,参数需要在语句本身中。

      ...
      HAVING C.userName IS NOT NULL 
      ORDER BY 
      CASE @condition
      WHEN 'joinDate' THEN joinDate
      ...
      

      您还应该在 CASE 语句的末尾有一个 ELSE 部分。

      请参阅案例页面的 C 部分。 http://msdn.microsoft.com/en-us/library/ms181765.aspx

      【讨论】:

        【解决方案4】:

        case 语句中,每个when 必须返回兼容的类型。在您的情况下,您需要三个 case 语句,一个用于字符串,一个用于数字,一个用于日期。

        order by
          CASE @condition
              WHEN 'joinDate' THEN joinDate
              WHEN 'dob' THEN dob
          END,
          CASE @condition
              WHEN 'userName' THEN userName
              WHEN 'Name' THEN (C.firstName+' '+C.lastName)
              WHEN 'userSatus' THEN userStatus
          END,
          CASE @condition
              WHEN 'totalPoints' THEN totalPoints
              WHEN 'totalPoints' THEN totalPoints
              WHEN 'Res' THEN COUNT(R.resID)
              WHEN 'PreOrd' THEN COUNT(P.orderID)
              WHEN 'DelOrd' THEN COUNT(D.orderID)
              WHEN 'Redeem' THEN COUNT(CR.securityCode)
          END;
        

        或者您可以将所有内容转换为文本:

              WHEN 'joinDate' THEN to_char( joinDate, 'yyyy-mm-dd' )
        

        只要确保表格的词法顺序与日期/数字顺序相同即可。

        另外,having 子句用于汇总结果。 C.userName IS NOT NULL 测试应该在 where 子句中,因为您使用它在甚至应用任何聚合函数之前过滤结果集。使用having 的示例类似于

        having COUNT(P.orderID) > 0
        

        这会在聚合函数返回值之后执行额外的过滤。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多