SQL第一次出现,最后出现

时间:2016-09-19 10:20:20

标签: php sql sql-server

让我们假设我们有这样的表:

UserID  ID    FLAG
 1      1      red
 2      2      white
 3      1      white
 4      2      green
 5      2     Brown
 6      5     White
 7      1     Blue
 8      3     Green
 9      4     Green
 10     2     Red
 11     4     Green
 12     3     Black

我想获得两个ID的第一个标志和最后一个标志。我尝试使用min / max函数,但它只给了我表的第一行和最后一行。我尝试使用"首先"也是,但显然它不适用于SQL Server。

第一次出现的期望输出:

ID    Flag
1      red
2      white
3      Green
4      Green
5      White

最后出现的期望输出:

ID    Flag
1         Blue
2         Red
3         Black
4         Green
5         White

5 个答案:

答案 0 :(得分:2)

如果您可以将“min”定义为按字母顺序排列的最小标志名称,并将max定义为按字母顺序排列的最大标志名称,则此处的一个选项是仅执行简单的GROUP BY查询:

SELECT ID,
       MIN(FLAG) AS minFlag,
       MAX(FLAG) AS maxFlag
FROM yourTable
GROUP BY ID

答案 1 :(得分:2)

您需要锚定定义排序条件的列 我们在您的示例数据上看到的顺序并不能确保排序与表中的排序相同 我添加了" ident"标识列编号从1到n的行..

然后,您可以将以下示例脚本与SQL First_Value() function

一起使用
--alter table flags add ident int identity(1,1)
select distinct
    id, 
    FIRST_VALUE(flag) over (partition by id order by ident) first,
    FIRST_VALUE(flag) over (partition by id order by ident desc) last
from flags

输出符合要求 enter image description here

答案 2 :(得分:1)

SQL表代表无序集。因此,除非另一列指定行,否则没有“第一”和“最后”行。

假设您有一个名为createdat的列,那么您可以使用row_number()。对于“第一”行:

select t.*
from (select t.*,
             row_number() over (partition by id order by createdat asc) as seqnum
      from t
     ) t
where seqnum = 1;

最后,您可以使用desc代替asc

答案 3 :(得分:0)

;WITH T AS
(
    SELECT 
        ID,
        Flag,
        ROW_NUMBER() OVER(PARTITION BY ID ORDER BY UserID) AS MinPartNo,
        ROW_NUMBER() OVER(PARTITION BY ID ORDER BY UserID Desc) AS MaxPartNo            
    FROM @tblTest
)
SELECT 
    ID,
    Flag AS FirstRows
FROM T
WHERE MaxPartNo=0

For Last Row:

SELECT 
    ID,
    Flag AS LastRows
FROM T
WHERE MinPartNo=1

答案 4 :(得分:0)

这不是一种流行的方法,但如果您没有任何标识列,则可以使用ROW_NUMBER() ... ORDER BY (SELECT NULL))

;WITH cte AS (
    SELECT  *,
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as RN
    FROM YourTable
)

SELECT TOP 1 WITH TIES 
                        c.ID,
                        c.FLAG,
                        c1.FLAG
FROM cte c
CROSS JOIN cte c1
WHERE c.ID = c1.ID
ORDER BY ROW_NUMBER() OVER (PARTITION BY c.ID ORDER BY c.RN, c1.RN DESC)

输出:

ID  FLAG    FLAG
2   white   Red
1   red     Blue
3   Green   Black
4   Green   Green
5   White   White