让我们假设我们有这样的表:
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
答案 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
答案 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