【问题标题】:CASE in Query of a QueryCASE in Query of a Query
【发布时间】:2018-01-16 13:06:38
【问题描述】:

在 ColdFusion 中,在查询了 MSSQL 数据库并使用 QueryAddRow 函数添加了几行之后,我需要通过对查询进行查询来重新排序查询。我需要的顺序要求我在 ORDER BY 子句中使用 CASE 表达式,如下所示:

<cfquery name="newquery" dbtype="query">
SELECT * FROM query
ORDER BY 
  CASE
    WHEN var LIKE 'All' THEN 'Zz'
    WHEN var LIKE '9%' THEN '0'
    ELSE var 
  END, year
</cfquery>

这会返回一个错误:Error Executing Database Query. Caught an exception, type = Database。我也尝试过使用QueryExecute

如果我直接查询数据库,查询工作得很好,所以当我尝试查询某个查询时,我只会得到一个错误。如果我删除 CASE 表达式并只执行 (...) ORDER BY var, year 查询的查询也可以正常工作,所以在我看来 CASE 在查询的查询中是不可能的。这是正确的,还是我应该能够以某种方式使用 CASE?

这是我需要重新排序的结构(在添加了三行之后)。显然,我已经删除了所有与手头问题无关的列。

year | var 
2001 | 9-12
2002 | 9-12
2003 | 9-12
2001 | 12+
2002 | 12+
2003 | 12+
2001 | All
2002 | All
2003 | All
2000 | 9-12
2000 | 12+
2000 | All

如您所见,我正在使用 CASE 通过自定义排序对 var 列进行排序。我对可能完全绕过这个问题的建议持开放态度。

如果有什么不清楚的地方请告诉我。

【问题讨论】:

  • "可能完全规避问题的建议" 如果您有能力修改表结构,请将名为“sortOrder”的列添加到包含“var”值和 ORDER BY SortOrder 的源表中.这将消除每次使用该列时对 CASE 的需要。另外,请考虑不要使用“var”作为列名。由于它是 CFML 中的保留字,因此在某些情况下可能会导致问题。
  • 不用担心,“var”只是我为示例选择的通用变量名称,而不是我在实践中使用的名称。看起来所有的建议和答案都指向制作一个排序列,所以这可能就是我要做的。
  • 手动添加的三行是什么?询问原因可能有更简单的选择...

标签: sql sql-server coldfusion case qoq


【解决方案1】:

Query of Queries 只支持某些东西 - case 结构出现在它不支持的那些东西之一。

我的建议是使用QueryAddColumn 将 sortBy 列添加到您的查询对象。然后遍历该查询并为该列分配适当的值。然后按 Q of Q 中的这一列排序。

或者,您可以简单地按照您所说的去做,并将逻辑合并到原始数据库查询中。

【讨论】:

    【解决方案2】:
    • 创建一个包含 CASE 表达式的列。
    • 在星号前添加此列
    • 使用按 1 排序

    【讨论】:

    • 投反对票。我测试了你的答案,它抛出了一个错误。
    • 而且按序号排序非常脆弱。如果查询更改了您的订单,则可能在错误的列上。
    • 我同意 Sean,这并不理想,但可以解决这个问题
    • @Sparky,如果您创建包含 CASE 表达式的列,它是结果的一部分。那么为什么不按该列排序,而不是按 ORDER BY 1 排序呢? :-)
    • 好点 Ageax,可能是我使用 ORDER BY 的坏习惯
    【解决方案3】:

    不熟悉 MSSQL(我使用 Oracle),看起来您在 ORDER BY 子句中创建了一个虚拟排序列。为什么不在原始 MSSQL 查询的 SELECT 子句中创建虚拟排序列?这样一来,它已经在 QoQ 中可用,无需任何额外的逻辑。当然,您需要 CFCASECFIF 代码来处理您的 QueryAddRow() 语句。

    您的初始 MSSQL 查询看起来像这样。

    <cfquery name="query" datasource="MSSQL_DSN">
    SELECT
        year,
        ...,
        var,
        CASE
            WHEN var LIKE 'All' THEN 'Zz'
            WHEN var LIKE '9%' THEN '0'
            ELSE var 
        END, myDummySortCol
    </cfquery>
    

    您的 QueryAddRow() 看起来像这样。

    <cfif varToAdd eq "All">
        <cfset QueryAddRow(query, {year="#yearToAdd#", ..., var="#varToAdd#", myDummySortCol="Zz"})>
    <cfelseif Left(varToAdd, 1) eq "9">
        <cfset QueryAddRow(query, {year="#yearToAdd#", ..., var="#varToAdd#", myDummySortCol="0"})>
    <cfelse>
        <cfset QueryAddRow(query, {year="#yearToAdd#", ..., var="#varToAdd#", myDummySortCol="#varToAdd#"})>
    </cfif>
    

    您的 QoQ 应该是这样的。

    <cfquery name="newquery" dbtype="query">
    SELECT * FROM query
    ORDER BY myDummySortCol
    </cfquery>
    

    【讨论】:

    • 您确定QueryAddRow 是适合这种情况的正确函数吗?
    • 是的,因为原始问题中的要求表明他需要在对原始查询执行一系列QueryAddRow() 语句后通过 QoQ 重新排序数据。我提供的解决方案考虑了这一要求。
    • Ageax -- 我不是原始发帖人,所以我不知道添加三行是为了什么。我根据他的要求回答了这个问题,他有一个从 MSSQL 返回的查询,然后他在查询完成后添加了 3 行,需要使用 QoQ。我的解决方案在添加行时创建了一个条件,以便 myDummySortCol 包含正确的重新排序值。所以我根据问题中提出的要求给出了完整的答案。
    • @Guest - 我不是在敲答案 :-) 我明白你为什么要这样回答。只能继续提供的信息。只是要求 OP 进行更多说明,因为可能还有其他选择...
    • @Ageax 抱歉,我认为您的评论是针对我的 :) 无论如何,作为您建议 OP 不应使用名为“var”的变量的附录,我还想补充他可能不应该使用名为“查询”的变量。我找不到任何显示它是保留字的东西,但它太笼统了。
    猜你喜欢
    • 2010-09-23
    • 2022-12-26
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    相关资源
    最近更新 更多