0

我有一个名为的记录集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()以某种顺序获取它们,我会收到一条错误消息,例如“位置 1 不是数字”,因为它具有 NULL 值。

这是ColdFusion可以做到的吗?我想它对记录集的某种旋转超出了我的能力。

4

3 回答 3

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>必须使用。

于 2015-01-20T12:31:45.767 回答
2

我最近不得不做类似的事情,并研究了 SQL Server 中的UNPIVOT。像大卫所说的那样,按照 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 小提琴

于 2015-01-20T16:08:19.927 回答
2

如果您愿意取消透视查询,则可以执行以下操作。我使用COALESCE()了代替ISNULL()(在这种情况下任何一个都有效,但COALESCE()都是 ANSI 标准)。该列tier_rank将给出给定层的排名——也就是说,具有最高值的层的排名为1. 如果有两个层都具有最高值,那么两者都将具有 intier_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

请在此处查看 SQL Fiddle 演示。

可能可以重新旋转上述未透视的查询,但我必须承认我这样做的尝试失败了。

于 2015-01-20T12:58:55.033 回答