SQL排名基于列中的值

时间:2015-09-30 17:18:14

标签: sql sql-server

我正在尝试根据结果中的值创建一些排名。 我的表由作业ID,日期和状态名称组成。 我正在尝试创建“Desired Group”,“Desired Rank”和“Date Diff”三个附加字段。我正在尝试使用StatusName列中的“Re-Initiated”这个词在我测量日期差异时重新启动时钟。最终目标是根据分组/排名获得日期差异字段。

所以,第一次“重新启动”发生在7月22日,响应也发生在7月22日 - 因此日期差异为零。第二次“重新启动”发生在9月23日,最后一次响应发生在9月26日,日期差异为3天。

任何想法都会很精彩!!

function cityData() {
    $db =& JFactory::getDBO();
    $query = $db->getQuery(true);

    $fieldlist = $db->qn(array('mls.MSTCITY')); // add the field names to an array
    $fieldlist[0] = 'distinct ' . $fieldlist[0]; //prepend the distinct keyword to the first field name  

    $query->select($fieldlist);
        ->from($db->qn('#__mls', 'mls'))
        ->order($db->qn('mls.MSTCITY'));

    $db->setQuery($query);
    $tbl = $db->loadObjectList();
    return $tbl;
}

2 个答案:

答案 0 :(得分:2)

您可以将所需的组计算为累计总和。等级和差异来自于:

select t.*,
       row_number() over (partition by id, grp order by date) as rnk,
       datediff(day, min(date) over (partition by id, grp), date) as diff
from (select t.*,
             sum(case when statusname = 'Re-Initiated' then 1 else 0 end) over (partition by id order by date) as grp
      from t
     ) t;

请注意,这会在每行上显示日期差异。如果只想要某些行,可以使用case语句。

答案 1 :(得分:0)

在SQL Server中可以使用Partion ByRow_number()

  • withRN:创建一个rowID
  • groupStart:计算哪个rowID开始新组
  • goupRange:从符合每个组的范围计算
  • previousStep:计算小组和排名
  • lastStep:计算每组的天数之差。
  • 最终查询加入previousSteplastStep

SQL Fiddle Demo

WITH withRN AS (
    SELECT [ID], [Date], [StatusName], [DesiredGroup], [DesiredRank], [DateDiff], 
        ROW_NUMBER() OVER 
          (ORDER BY [DATE], CASE WHEN [StatusName] = 'Re-Initiated' THEN 0 ELSE 1 END) as RN
    FROM Table1
),
groupStart AS (
    SELECT *, 
        ROW_NUMBER() OVER (ORDER BY RN) groupID
    FROM withRN T1
    WHERE T1.[StatusName] = 'Re-Initiated'
),
groupRange AS (
    SELECT G1.RN as rnStart, G2.RN  rnEnd, G1.groupID
    FROM groupStart G1
    LEFT JOIN groupStart G2
      ON G1.groupID = G2.groupID - 1
),
previousStep AS (
    SELECT W.ID, W.[Date], W.[StatusName], W.[DesiredGroup], W.[DesiredRank], W.[DateDiff], W.RN, G.groupID,
           ROW_NUMBER() OVER (PARTITION BY G.groupID ORDER BY W.[Date]) as DesireRank2
    FROM withRN W
    INNER JOIN  groupRange G
      ON W.RN >= G.rnStart
     AND W.RN < CASE 
                  WHEN G.rnEnd IS NULL THEN 999999999999
                  ELSE G.rnEnd
                END
),
lastStep AS (
   SELECT groupID, DATEDIFF ( dd, MIN([Date]), MAX([Date])) as dayD , MAX(RN) as diffRow
   FROM previousStep
   GROUP BY groupID
)
SELECT P.ID, P.[Date], P.[StatusName], P.[DesiredGroup], P.[DesiredRank], P.[DateDiff], P.groupID, P.DesireRank2, L.dayD
FROM previousStep P
LEFT JOIN lastStep L
  ON P.RN = L.diffRow