SQL Server 如何在SQL中创建每个客户的第一个日期标志列?

dy2hfwbg  于 2022-12-22  发布在  其他
关注(0)|答案(3)|浏览(165)

我在SQL Server中有一个如下所示的表:
| 客户名称|客户端ID|采购_日期|
| - ------| - ------| - ------|
| 约翰·迪|小行星2563| 2022年11月15日|
| 约翰·迪|小行星2563|二零二二年十一月二十九日|
| 萨拉·斯宾塞|小行星7985|二零二二年四月十七日|
| 萨拉·斯宾塞|小行星7985| 2022年5月12日|
| 萨拉·斯宾塞|小行星7985|二○二二年七月十五日|
| 马克·布朗|小行星8635|二○二一年一月二十三日|
| 马克·布朗|小行星8635|二○二一年一月三十日|
| 马克·布朗|小行星8635|二○二一年六月二十日|
我需要一个查询来创建一个标志列,以标识每个客户端的首次购买日期,预期结果如下:
| 客户名称|客户端ID|采购_日期|首次_购买_标志|
| - ------| - ------| - ------| - ------|
| 约翰·迪|小行星2563| 2022年11月15日|1个|
| 约翰·迪|小行星2563|二零二二年十一月二十九日|无|
| 萨拉·斯宾塞|小行星7985|二零二二年四月十七日|1个|
| 萨拉·斯宾塞|小行星7985| 2022年5月12日|无|
| 萨拉·斯宾塞|小行星7985|二○二二年七月十五日|无|
| 马克·布朗|小行星8635|二○二一年一月二十三日|1个|
| 马克·布朗|小行星8635|二○二一年一月三十日|无|
| 马克·布朗|小行星8635|二○二一年六月二十日|无|
是否有任何解决方案可以使用case语句创建标志列?我在表中有数千行和数十列。
我试过了,但好像不起作用。

CASE 
WHEN Purchase_Date = MIN(Purchase_Date) OVER (ORDER BY Client_ID) THEN 1 
ELSE 0 
END AS First_Purchase_Flag

版本

Microsoft SQL Server 2019 (RTM-CU15) (KB5008996) - 15.0.4198.2 (X64) Jan 12 2022 22:30:08 Copyright (C) 2019 Microsoft Corporation
Enterprise Edition (64-bit) on Windows Server 2016 Datacenter 10.0 (Build 14393: ) (Hypervisor)
uplii1fm

uplii1fm1#

您可以使用 * 窗口功能 *,但如下所示:

CASE WHEN Purchase_Date = MIN(Purchase_Date) OVER (PARTITION BY Client_Id) THEN 1 ELSE 0 END

另一种选择是

CASE WHEN Purchase_Date = FIRST_VALUE(Purchase_Date) OVER (PARTITION by Client_Id order by Purchase_Date ) THEN 1 ELSE 0 END

在任何一种情况下,您都将每个Client_Id作为一个组来处理,因此您将按此进行 * 分区 *。

qf9go6mv

qf9go6mv2#

嗨,在这种情况下,您将需要使用row_number()创建一个窗口函数。窗口函数将在窗口上应用该函数,您可以将其视为一个组。在下面的代码中,row_number()函数将在由client_names创建的组上应用

select
Client_Name,
Client_ID,
Purchase_Date,
row_number() over (partition by client_name order by Purchase_Date desc) as First_Purchase_Flag

然后可以创建case语句,用数字1标记所有行

select
Client_Name,
Client_ID,
Purchase_Date,
First_Purchase_Flag,
case when First_Purchase_Flag = 1 then 1 else 0 end as First_Purchase_Ind
e3bfsja2

e3bfsja23#

CREATE TABLE #TestTable
(
    Client_Name NVARCHAR(100),
    Client_ID INT,
    Purchase_Date DATE
)

INSERT INTO #TestTable (Client_Name,Client_ID,Purchase_Date)
SELECT * FROM
(
VALUES
    ('John Dee',2563,'11/15/2022'),
    ('John Dee',2563,'11/29/2022'),
    ('Sara Spence',7985,'4/17/2022'),
    ('Sara Spence',7985,'5/12/2022'),
    ('Sara Spence',7985,'7/15/2022'),
    ('Mark Brown',8635,'1/23/2021'),
    ('Mark Brown',8635,'1/30/2021'),
    ('Mark Brown',8635,'6/20/2021')
) As RawData (Client_Name,Client_ID,Purchase_Date)

;WITH CTE
AS
(
    SELECT 
        Client_Name,
        Client_ID,
        Purchase_Date,
        ROW_NUMBER() OVER (PARTITION BY Client_ID ORDER BY Purchase_Date ASC) AS PurchaseOrdinal
    FROM #TestTable
)

    SELECT 
        Client_Name,
        Client_ID,
        Purchase_Date,
        IIF(PurchaseOrdinal = 1, 1, 0) AS First_Purchase_Flag
    FROM CTE

相关问题