0

我有以下查询

SELECT  Cod ,
        MIN(Id) AS id_Min,
        -- retrieve value min in the middle as id_Min_Middle,
        -- retrieve value max in the middle as id_Max_Middle,
        MAX(Id) AS id_Max,            
        COUNT(*) AS Tot
FROM    Table a ( NOLOCK )        
GROUP BY Cod
HAVING  COUNT(*)=4

我怎样才能像对 and 所做的那样检索and之间min的值?如果我使用我得到的and ,但不是我想要的值。maxminmax(SUM(Id) - (MIN(Id)+MAX(Id))summiddle minmax

例子

Cod      |  Id

Stack       10
Stack       15
Stack       11
Stack       40
Overflow    1
Overflow    120
Overflow    15
Overflow    100

所需输出

Cod         | Min   | Min_In_The_Middle | Max_In_The_Middle | Max

Stack         10          11                   15               40
Overflow      1           15                  100               120
4

4 回答 4

1

我不确定您的问题被标记plsql sql-server. 但我假设您正在使用支持 CTE 和窗口函数的数据库系统。

为了概括您一直在尝试做的事情,首先将行号分配给行,然后使用您想要实现枢轴的任何技术:

;WITH OrderedValues as (
    SELECT Cod,Id,ROW_NUMBER() OVER (PARTITION BY Cod ORDER BY Id) as rn
       COUNT(*) OVER (PARTITION BY Cod) as Cnt
    FROM Table (NOLOCK)
), With4Values as (
    SELECT * from OrderedValues where Cnt=4
)
SELECT Cod,
    --However you want to do the pivot. Here I'll use MAX/CASE
    MAX(CASE WHEN rn=1 THEN Id END) as Value1,
    MAX(CASE WHEN rn=2 THEN Id END) as Value2,
    MAX(CASE WHEN rn=3 THEN Id END) as Value3,
    MAX(CASE WHEN rn=4 THEN Id END) as Value4
FROM
    With4Values
GROUP BY
    Cod

希望您可以看到,与回答有关 3 行或 4 行的过于具体的问题相比,这更容易扩展到更多列。但是,如果您需要处理任意数量的列,则必须切换到动态 SQL。

于 2012-04-18T12:39:24.537 回答
1

试试这个,祝你好运

WITH temp AS
         (SELECT   cod, MIN (ID) min_id, MAX (ID) max_id
              FROM tab
          GROUP BY cod
            HAVING COUNT (ID) = 4)
    SELECT code, temp.min_id,
           (SELECT   MIN (ID)
                FROM tab
               WHERE cod = temp.cod AND ID NOT IN (temp.min_id)
            GROUP BY cod) min_mid_id,
           (SELECT   MAX (ID)
                FROM tab
               WHERE cod = temp.cod AND ID NOT IN (temp.max_id)
            GROUP BY cod) max_min_id, temp.max_id
      FROM temp;
于 2012-04-18T13:01:19.263 回答
1

只有一个(这里[Table|[Clustered] Index]]Scan有演示):

SELECT  pvt.Cod,
        pvt.[1] AS MinValue,
        pvt.[2] AS MinInterValue,
        pvt.[3] AS MaxInterValue,
        pvt.[4] AS MaxValue
FROM
(
        SELECT  x.Cod, x.ID, x.RowNumAsc
        FROM
        (
                SELECT  *,
                        ROW_NUMBER() OVER(PARTITION BY t.Cod ORDER BY t.ID ASC) RowNumAsc,
                        ROW_NUMBER() OVER(PARTITION BY t.Cod ORDER BY t.ID DESC) RowNumDesc
                FROM    MyTable t
        ) x
        WHERE   x.RowNumAsc = 1 AND x.RowNumDesc = 4
        OR      x.RowNumAsc = 2 AND x.RowNumDesc = 3
        OR      x.RowNumAsc = 3 AND x.RowNumDesc = 2
        OR      x.RowNumAsc = 4 AND x.RowNumDesc = 1

) y
PIVOT   ( MAX(y.ID) FOR y.RowNumAsc IN ([1], [2], [3], [4]) ) pvt;
于 2012-04-18T13:03:53.880 回答
0

我知道您想排除极值并找到其余的最小值和最大值。这是我想到的,但我没有机会运行和测试它......

WITH Extremes AS ( SELECT Cod, MAX(ID) AS Id_Max, MIN(ID) AS Id_Min 
                    FROM [Table] a GROUP BY Cod)
SELECT 
  e.Cod,
  e.Id_Min,
  MIN(a.Id) AS id_Min_Middle,
  MAX(a.Id) AS id_Max_Middle,
  e.Id_Max
FROM Extremes e
LEFT JOIN [Table] a ON a.Cod = e.Cod AND a.Id > e.Id_Min AND a.Id < e.Id_Max
GROUP BY e.Cod
于 2012-04-18T12:16:56.593 回答