Sql 如何选择最近6个月内存在的所有记录?

Sql 如何选择最近6个月内存在的所有记录?,sql,sql-server,tsql,Sql,Sql Server,Tsql,有人能建议我如何选择最近N个月内存在的所有记录吗 N将是参数 我已经写了下面的子查询来返回所需的结果。但这不是动态的,因为我无法通过N个月的数量来选择上N个月的记录 SELECT DISTINCT supplier_code FROM API_StockAndSaleHeader WHERE supplier_code IN (SELECT supplier_code FROM API_StockAndSaleHeader WHERE dbo.ConvertStringToDate(peri

有人能建议我如何选择最近N个月内存在的所有记录吗

N将是参数

我已经写了下面的子查询来返回所需的结果。但这不是动态的,因为我无法通过N个月的数量来选择上N个月的记录

SELECT DISTINCT supplier_code
FROM API_StockAndSaleHeader
WHERE supplier_code IN
(SELECT supplier_code
 FROM API_StockAndSaleHeader
 WHERE dbo.ConvertStringToDate(period_start_date) = '2020-03-01')
 AND supplier_code IN
(SELECT supplier_code
 FROM API_StockAndSaleHeader
 WHERE dbo.ConvertStringToDate(period_start_date) = '2020-02-01')
 AND supplier_code IN
(SELECT supplier_code
 FROM API_StockAndSaleHeader
 WHERE dbo.ConvertStringToDate(period_start_date) = '2020-01-01')
 AND supplier_code IN
(SELECT supplier_code
 FROM API_StockAndSaleHeader
 WHERE dbo.ConvertStringToDate(period_start_date) = '2019-12-01')
 AND supplier_code IN
(SELECT supplier_code
 FROM API_StockAndSaleHeader
 WHERE dbo.ConvertStringToDate(period_start_date) = '2019-11-01')

这将为您提供过去N个月内每个月至少有一个条目的供应商:

declare @N as INT = 6;

WITH CTE AS
(
    SELECT DISTINCT supplier_code, CONVERT(varchar(6), CONVERT(date, period_start_date), 112) start_month
    FROM API_StockAndSaleHeader
    WHERE CONVERT(date, period_start_date) >= DATEADD(month, -@N, CONVERT(date, GETDATE()))
)
SELECT supplier_code
FROM CTE
GROUP BY supplier_code
HAVING COUNT(*) >= @N;
这首先获得一组不同的供应商代码+月份的辅助集合,以便知道哪些供应商在过去6个月内至少有一个记录。诀窍是将日期转换为varchar,并将其修剪为6个字符,得到yyyymm格式。然后你只需要那些至少有N条记录的,这意味着所有N个月都有数据。我使用>=只是为了安全起见,这取决于你如何划分月份。每30/31?从今天算起30天

注意,我使用CONVERT来转换为日期。顺便说一句,将日期存储为其他类型是件坏事

使用此数据,它将仅显示供应商1:


注意:供应商2在上个月有6个以上的条目,但在过去N个月中没有每个条目。

您是否尝试过,例如dbo.ConvertStringToDateperiod\u start\u date>=DATEADDmonth,-N,CONVERTdate,GETDATE?这是将当前时间转换为日期,然后减去N个月。更新:哦,你需要过去N个月里每个月发生的记录,对吗?还在吗?我的答案对你有用吗?不需要使用事务,也不需要删除表。无论如何,您正在删除不存在的临时文件。沙哈布已经有了那张桌子,所以他需要从剧本中删除很多东西才能让它为他工作。最好发布OP需要的脚本,然后在单独的块中,为我们其他人提供一个没有数据的测试用例@不使用当前月份的第一天,如果您已经按照单个字段进行分组,则不需要使用distinct。@Andrew我总是在编写任何代码之前编写begin/rollback。这不是一个坏习惯。我还想让任何没有该表的人编写可测试的代码,这样我就可以证明它给出了正确的结果!感谢您提供的快速结果。我得到了它。你们俩都很棒。
    CREATE TABLE #API_StockAndSaleHeader 
    (
        supplier_code int,
        period_start_date DATETIME
    )

    INSERT INTO #API_StockAndSaleHeader (supplier_code, period_start_date) VALUES
    (1, '2020-05-01'),
    (1, '2020-04-01'),
    (1, '2020-04-15'), -- This one should not show up.
    (2, '2020-05-01'),
    (2, '2020-04-01'),
    (2, '2020-03-01'), -- This one should show up.
    (2, '2020-02-01'),
    (2, '2020-01-01')

    DECLARE @months int = 3

    SELECT supplier_code 
    FROM 
    (
        SELECT supplier_code, DATEPART(year, period_start_date) as [Year], DATEPART(month, period_start_date) as [month]--DISTINCT supplier_code
        FROM #API_StockAndSaleHeader 
        WHERE DATEADD(MONTH, @months, period_start_date) >= GETDATE()
        GROUP BY supplier_code, DATEPART(year, period_start_date), DATEPART(month, period_start_date)
    ) A
    GROUP BY supplier_code
    HAVING COUNT(supplier_code) >= @months

    IF(OBJECT_ID('tempdb..#API_StockAndSaleHeader') IS NOT NULL)
    BEGIN
        DROP TABLE #Temp
    END
    CREATE TABLE #API_StockAndSaleHeader 
    (
        supplier_code int,
        period_start_date DATETIME
    )

    INSERT INTO #API_StockAndSaleHeader (supplier_code, period_start_date) VALUES
    (1, '2020-05-01'),
    (1, '2020-04-01'),
    (1, '2020-04-15'), -- This one should not show up.
    (2, '2020-05-01'),
    (2, '2020-04-01'),
    (2, '2020-03-01'), -- This one should show up.
    (2, '2020-02-01'),
    (2, '2020-01-01')

    DECLARE @months int = 3

    SELECT supplier_code 
    FROM 
    (
        SELECT supplier_code, DATEPART(year, period_start_date) as [Year], DATEPART(month, period_start_date) as [month]--DISTINCT supplier_code
        FROM #API_StockAndSaleHeader 
        WHERE DATEADD(MONTH, @months, period_start_date) >= GETDATE()
        GROUP BY supplier_code, DATEPART(year, period_start_date), DATEPART(month, period_start_date)
    ) A
    GROUP BY supplier_code
    HAVING COUNT(supplier_code) >= @months

    IF(OBJECT_ID('tempdb..#API_StockAndSaleHeader') IS NOT NULL)
    BEGIN
        DROP TABLE #Temp
    END