SQL Server: извлекайте уникальные строки за определенный год, но не, если они были созданы ранее - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть запрос, который показывает список продуктов в 2018 году.

Я хочу просмотреть продукты, если они были созданы уникальным образом в 2018 году и не должны отображаться, если они были созданы ранее в течениепример в 2017 году или около того.

Вот мой SQL:

CREATE TABLE [dbo].[Products]
(
    [GTIN] [VARCHAR](50) NULL,
    [Location] [INT] NULL,
    [Date] [DATETIME] NULL
) ON [PRIMARY]
GO

INSERT INTO Products123(GTIN, Location, Date)
VALUES (12345678911, 1, '2017-01-01 00:00:00.000'),
       (12345678911, 1, '2018-01-01 00:00:00.000'),
       (12345678912, 1, '2018-02-01 00:00:00.000'),
       (12345678913, 1, '2018-03-01 00:00:00.000'),
       (12345678914, 1, '2018-03-01 00:00:00.000'),
       (12345678915, 1, '2018-04-01 00:00:00.000'),
       (12345678916, 1, '2018-05-01 00:00:00.000'),
       (12345678917, 1, '2018-06-01 00:00:00.000'),
       (12345678918, 1, '2018-07-01 00:00:00.000');

Мой запрос:

SELECT 
    DATENAME(MONTH, DATE) AS Dato,
    COUNT(DISTINCT GTIN) AS PRODUCTS
FROM 
    (SELECT  
         GTIN, DATE = MIN(DATE)
     FROM     
         Products
     WHERE 
         YEAR(DATE) = '2018' 
         AND YEAR(DATE) NOT IN (2017)
     GROUP BY
         GTIN) d
GROUP BY
    MONTH(DATE), DATENAME(MONTH, DATE)
ORDER BY   
    MONTH(DATE)

Результат:

Dato    |   Products
January |     1
February|     1
April   |     2
May     |     1
June    |     1
July    |     1

ОжидаетсяРезультат:

Dato    |   Products
January |     0
February|     1
April   |     2
May     |     1
June    |     1
July    |     1

Январь должен быть нулевым, поскольку продукт уже создан в 2017 году (или ранее) и поэтому больше не является уникальным.Может кто-нибудь помочь, как получить правильный список

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Вместо этого используется Таблица календаря , но, возможно, вы получите то, что вам нужно?

WITH CTE AS(
    SELECT CT.CalendarDate,
           CT.CalendarMonth,
           CT.CalendarMonthName,           
           P.GTIN,
           P.[Location],
           P.[Date],
           MIN(P.[date]) OVER (PARTITION BY P.GTIN) AS MinDate
    FROM dbo.CalendarTable CT
         LEFT JOIN dbo.Products P ON CT.CalendarDate = P.[date]
    WHERE CT.CalendarYear IN (2017,2018))
SELECT CTE.CalendarMonth,
       CTE.CalendarMonthName,
       COUNT(DISTINCT CASE WHEN CTE.MinDate > '20180101' THEN CTE.GTIN END) AS Products
FROM CTE
GROUP BY CTE.CalendarMonth,
         CTE.CalendarMonthName
ORDER BY CTE.CalendarMonth;
0 голосов
/ 23 ноября 2018

Вы можете просто использовать NOT EXISTS:

WITH products2018 AS (
    SELECT *
    FROM @Products AS p
    WHERE Date >= '2018-01-01'
    AND NOT EXISTS (
        SELECT *
        FROM @Products AS x
        WHERE GTIN = p.GTIN
        AND Date < '2018-01-01'
    )
)
SELECT DATENAME(MONTH, d), COUNT(products2018.GTIN)
FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11)) AS numbers(n)
CROSS APPLY (SELECT DATEADD(MONTH, n, '2018-01-01')) AS dates(d)
LEFT JOIN products2018 ON YEAR(products2018.Date) = YEAR(d) AND MONTH(products2018.Date) = MONTH(d)
GROUP BY d
ORDER BY d
...