Фильтровать по результатам, где ROW_NUMBER превышает 1 - PullRequest
0 голосов
/ 30 апреля 2018

Мне удалось получить некоторые упорядоченные результаты, используя ROW_NUMBER() и разделенные по коду страны и клиенту, упорядоченные по дате котировки. Столбец ROW_NUMBER() называется PRank.

CountryCode  ¦   ClientRef   ¦   Quote Ref   ¦   Name     ¦    Address     ¦   PostCode   ¦   PreferencesCode   ¦   QuoteDate         ¦   PolicyType   ¦   PRank   ¦
     0           AABB001         AABB001MB1    Mr A Smith   1 Country Lane     WA21 2PU       5934611             2017-03-18 00:00:00     MB               1
     0           AABB001         AABBMM1MB2    Mr A Smith   1 Country Lane     WA21 2PU       5934611             2017-03-18 00:00:00     MB               2
     0           AABB001         AABBMM1MB3    Mr A Smith   1 Country Lane     WA21 2PU       5934611             2017-03-18 00:00:00     MB               3
     0           BBGG003         BBGG003MB1    Mrs B Jones  2 City Road        M1 3XY         312191              2017-09-02 00:00:00     MB               1

Это код для моего ROW_NUMBER() столбца:

ROW_NUMBER() OVER(PARTITION BY CountryCode, ClientRef, QuoteDate 
                  ORDER BY QuoteDate DESC, PolicyRef asc)

Есть много результатов, как в последнем ряду; они учитываются только до 1, потому что на указанную дату у клиента была только одна цитата. Я хочу исключить эти строки, не удаляя ни одной строки из результатов клиента, если в одну и ту же дату произошли множественные кавычки (т.е. я все еще хочу видеть все три строки первого клиента в результатах выше), поэтому я решил использовать CTE и фильтрацию на ROW_NUMBER приведет к потере данных из результатов, которые мне еще нужно увидеть.

Я пытался что-то сделать с HAVING и суммировать столбец PRank, но я не мог выяснить группировку, поскольку я не хочу на самом деле агрегировать данные, просто избавился от любых строк, где у ClientRef есть только один QuoteRef в день.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Я думаю, вы хотите что-то вроде следующего.

;WITH Rankings AS
(
    -- Your query here
    SELECT
        CountryCode = 1,
        ClientRef = 1,
        QuoteDate = 1,
        PRank = 1
),
Only1Record AS
(
    SELECT
        R.CountryCode, 
        R.ClientRef, 
        R.QuoteDate
    FROM
        Rankings AS R
    GROUP BY
        R.CountryCode, 
        R.ClientRef, 
        R.QuoteDate
    HAVING
        MAX(R.PRank) = 1
)
DELETE D FROM
    Only1Record AS R
    INNER JOIN Rankings AS D ON
        R.CountryCode = D.CountryCode AND
        R.ClientRef = D.ClientRef AND
        R.QuoteDate = D.QuoteDate

Еще один более простой вариант - использование оконного COUNT().

;WITH Rankings AS
(
    -- Your query here
    SELECT
        CountryCode = 1,
        ClientRef = 1,
        QuoteDate = 1,
        PRank = 1,
        Total = COUNT(1) OVER (PARTITION BY CountryCode, ClientRef, QuoteDate)
)
DELETE D FROM
    Rankings AS D
WHERE
    D.Total = 1
0 голосов
/ 30 апреля 2018

Если вы ищете клиентов с более чем 1 котировкой в ​​день, CTE все равно будет лучшим вариантом.

Если предположить, что это противоречит представлению ic_dapolicy в InfocentrePlus (это, очевидно, данные OpenGI, а таблицы icp не так просты в использовании), тогда ваш запрос будет выглядеть примерно так:

WITH Quotes AS(
    SELECT *,
           COUNT(*) OVER (PARTITION BY PPY.B@, PPY.Ref@) AS ClientQuotes 
    FROM ic_Dapolicy PPY
    WHERE PPY.Quote_date = @Quote_date) --If you aren't filtering on Quote_date in your where, add it to the PARTITION BY clause
SELECT [YourColumns]
FROM Quotes
WHERE ClientQuotes > 1;
...