如何按不同列中的值排序查询

时间:2015-01-20 00:34:56

标签: coldfusion sql-server-2012 coldfusion-11

我有一个名为rsProductClass的记录集,它是从数据库中的表返回的。这是一个非常简单的SELECT * FROM Table WHERE ProductID = {ID Value Here},表格如下:

ProductID | UPPERTIER | LOWERTIER | NATIER  | OTHERTIER
1           20          60          10        10
2           10          90          NULL      NULL
3           NULL        40          NULL      5

该表可能具有或不具有各层的值。

我想要做的是向用户显示哪个列具有最高值以及该列的名称是什么。例如,如果您查看ProductID 2,则页面应显示"这可能是LOWERTIER产品"

我需要对rsProductClass查询进行排序,使其返回该查询中按每列中的值排序的列的列表。我想将NULL值视为零。

我试图在执行valuelist()和一些ArrayToList()类型函数时搞乱,但它会在NULL值上崩溃。假设我将列添加到数组中,然后使用ArraySort()以某种顺序获取它们,我会收到类似&#34的错误;位置1不是数字"因为它有一个NULL值。

这可以通过ColdFusion完成吗?我想它是记录集的某种旋转,这超出了我的能力。

3 个答案:

答案 0 :(得分:2)

这样的事情会起作用:

<cfquery name="tiers" datasource="...">
    SELECT ProductID, UPPERTIER VALUE, 'UPPERTIER' TIER
    WHERE  UPPERTIER IS NOT NULL
    UNION 
    SELECT ProductID, LOWERTIER VALUE, 'LOWERTIER' TIER
    WHERE  LOWERTIER IS NOT NULL
    UNION
    SELECT ProductID, OTHERTIER VALUE, 'OTHERTIER' TIER
    WHERE  OTHERTIER IS NOT NULL
    UNION
    SELECT ProductID, NATIER VALUE, 'NATIER' TIER
    WHERE  NATIER IS NOT NULL
    ORDER BY ProductID, VALUE
</cfquery>

<cfset productGroup = StructNew()>

<cfoutput query="tiers" group="ProductID">
  <cfset productGroup[ProductID].TIER = TIER>
  <cfset productGroup[ProductID].VALUE = VALUE>
</cfoutput>

<cfdump var="#productGroup#">

从ColdFusion 10开始,您可以使用<cfloop query="..." group="...">,然后才能使用<cfoutput>

答案 1 :(得分:2)

如果您愿意取消查询,则可能会执行以下操作。我使用COALESCE()而不是ISNULL()(在这种情况下,任何一个都可以工作,但COALESCE()是ANSI标准)。列tier_rank将给出给定层的等级 - 也就是说,具有最高值的层将具有等级1。如果有两个层都具有最高值,则两个层的值都会tier_rank 1(这就是为什么您要使用RANK()而不是ROW_NUMBER() - - 如果它更符合您的要求,您也可以使用DENSE_RANK()

SELECT p1.product_id, p1.tier_name, p1.tier_value
     , RANK() OVER ( PARTITION BY p1.product_id ORDER BY p1.tier_value DESC ) tier_rank
  FROM (
  SELECT product_id, 'UPPERTIER' AS tier_name
       , COALESCE(uppertier, 0) AS tier_value
    FROM products
   UNION ALL
  SELECT product_id, 'LOWERTIER' AS tier_name
       , COALESCE(lowertier, 0) AS tier_value
    FROM products
   UNION ALL
  SELECT product_id, 'NATIER' AS tier_name
       , COALESCE(natier, 0) AS tier_value
    FROM products
   UNION ALL
  SELECT product_id, 'OTHERTIER' AS tier_name
       , COALESCE(othertier, 0) AS tier_value
    FROM products
) p1

Please see SQL Fiddle demo here.

有可能重新调整上述不透明的查询,但我必须承认我这样做的尝试失败了。

答案 2 :(得分:2)

我最近不得不做类似的事情并在SQL Server中查看UNPIVOT。像大卫所说的那样建议你打开你的查询,你可以做这样的事情。这不会添加RANK列,但会对值进行排序。

SELECT ProductID, Tier, TierValue
FROM
(SELECT ProductID, ISNULL(UpperTier,0) UpperTier, ISNULL(LowerTier,0) LowerTier, ISNULL(NaTier,0) NaTier, ISNULL(OtherTier,0) OtherTier
FROM products) p
UNPIVOT
(TierValue FOR Tier IN 
(UpperTier, LowerTier, NaTier, OtherTier)
)AS unpvt
ORDER BY ProductID, TierValue Desc

SQL FIDDLE