2014-08-29 4 views
0

Я пытаюсь создать сохраненный вид в MSSQL, который возвращает список предложений, которые были приняты. Проблема, с которой я сталкиваюсь, заключается в том, что если предложение имеет более одной версии, оно возвращает все строки, принятые, хотя это действительно только последняя версия.SQL извлекает отдельные строки по номеру версии

Идентификатор запроса отличается для каждой записи заявки, но номер котировки и имя совпадают. Способ определить, какой идентификатор записи котировки мы хотели бы вернуть, будет предложение с последним номером версии. Только несколько цитат имеют номера версий, и большинство из них уникальны для начала.

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

Вот пример формата данных, я имею в виду

Quote ID | Quote Number | Quote Name  | Version | 

i3hfkdkj | 101 | John Smith Residence | 1 | 
fheifjdh | 102 | Big Apple Food Service | 1 | 
kdjfnf98 | 103 | Starbucks Coffee  | 1 | 
3498fhkd | 101 | John Smith Residence | 2 | 
jfh3bfi3 | 104 | Susan Jane Apartment | 1 | 
9834jfkd | 101 | John Smith Residence | 3 | 

В идеале я хотел бы запрос только возвращать следующие строки

fheifjdh | 102 | Big Apple Food Service | 1 | 
kdjfnf98 | 103 | Starbucks Coffee  | 1 | 
jfh3bfi3 | 104 | Susan Jane Apartment | 1 | 
9834jfkd | 101 | John Smith Residence | 3 | 

Большое вам спасибо заранее Ваша помощь

Dan

Вот синтаксис для моего текущего ск который работает правильно, за исключением перечисленных выше.

SELECT 
dbo.Quote_Main.quote_readable_id, 
dbo.Quote_Main.quote_name, 
dbo.Quote_Main.account_name, 
dbo.Quote_Main.contact_name, 
dbo.Quote_Main.quote_status, 
dbo.Quote_Main.delivered_date, 
dbo.Quote_Customers.first_name, 
dbo.Quote_Customers.last_name, 
dbo.Quote_Customers.customer_source, 
dbo.Quote_Main.idCRM_opportunity, 
dbo.Quote_Main.idQuote_Main, 
dbo.Quote_Items.item_notes_html AS QuoteScope, 
dbo.Quote_Items.item_notes, 
dbo.Quote_Main.version 

FROM 
dbo.Quote_Items 
LEFT JOIN dbo.Quote_Main ON dbo.Quote_Items.idQuote_Main = dbo.Quote_Main.idQuote_Main 
LEFT JOIN dbo.Quote_Customers ON dbo.Quote_Main.idQuote_Main = dbo.Quote_Customers.idQuote_Main 
WHERE 
dbo.Quote_Items.long_description = 'Proposal Scope' AND 
dbo.Quote_Main.quote_status = 'Won' AND 
dbo.Quote_Customers.usage_type = 'Quote To' 
+0

Посмотрите на предложение GROUP BY и 'MIN()'. –

+1

Какое программное обеспечение SQL? – Blorgbeard

+0

Microsoft SQL Server. Я также добавил дополнительную информацию: –

ответ

1

Если вы используете SQL Server, вы можете использовать row_number():

select * 
from (
    select *, 
     row_number() over (partition by [Quote Number] order by Version desc) [rn] 
    from Quotes 
) x 
where x.rn=1 

Это присваивает номер каждой строке - номер упорядочен по версии (по убыванию), и перезагружается для каждой цитаты номер. Результат подзапроса выглядит следующим образом:

Quote ID | Quote# | Quote Name    | Version | rn | 

i3hfkdkj | 101 | John Smith Residence | 1 | 3 | 
fheifjdh | 102 | Big Apple Food Service | 1 | 1 | 
kdjfnf98 | 103 | Starbucks Coffee  | 1 | 1 | 
3498fhkd | 101 | John Smith Residence | 2 | 2 | 
jfh3bfi3 | 104 | Susan Jane Apartment | 1 | 1 | 
9834jfkd | 101 | John Smith Residence | 3 | 1 | 

Тогда мы просто фильтровать по rn=1.

Подзапрос необходим, потому что row_number() не может использоваться в предложении where.

+1

или любые dbms, поддерживающие ROW_NUMBER(), такие как Oracle –

+0

Действительно. Я не уверен, что синтаксис точно такой же. – Blorgbeard

+0

да, если бы вы не использовали [] для обозначения полей, вы просто не указали «как» из x, которые Ora не захочет ни –

2

Один подход с not exists:

select p.* 
from proposals p 
where not exists (select 1 
        from proposals p2 
        where p2.QuoteNumber = p.QuoteNumber and p2.version > p.version 
       ); 

Вы не уточняют, что базы данных вы используете, и это должно работать в основном все базы данных для представления.

EDIT:

Просто используйте КТР:

with proposals as (
     <your query here> 
    ) 
select p.* 
from proposals p 
where not exists (select 1 
        from proposals p2 
        where p2.QuoteNumber = p.QuoteNumber and p2.version > p.version 
       ); 

Я бы запустить этот первый, чтобы увидеть, если он имеет достаточную производительность. Если нет, возможно, есть смысл для оптимизации.

+0

Я добавил свой код в сообщение. Можете ли вы показать мне синтаксис, который вы имеете в виду с моим кодом? Благодаря! –

-1

просто навалить немного

select quoteid,quotenum,quotename,ver from quotes q 
where quotenum||ver = (select max(quotenum||ver) from quotes q2 
         where q.quotenum=q2.quotenum) 
1

По желанию это обрабатывались пример применительно к добавленному запросу в ответе.

Общая структура этого запроса изменилась с оригинала, перемещая таблицу dbo.Quote_Main в порядке приоритета и обратно dbo.Quote_Items вниз.

SELECT 
     QM.quote_readable_id 
    , QM.quote_name 
    , QM.account_name 
    , QM.contact_name 
    , QM.quote_status 
    , QM.delivered_date 
    , QC.first_name 
    , QC.last_name 
    , QC.customer_source 
    , QM.idCRM_opportunity 
    , QM.idQuote_Main 
    , QI.item_notes_html AS QuoteScope 
    , QI.item_notes 
    , QM.version 

FROM dbo.Quote_Main QM 
     INNER JOIN dbo.Quote_Customers 
        ON QM.idQuote_Main = QC.idQuote_Main 
     LEFT OUTER JOIN (
         SELECT 
           idQuote_Main 
          , item_notes_html 
          , item_notes 
-- note 1 
          , ROW_NUMBER() OVER (PARTITION BY idQuote_Main 
               ORDER BY qi_version DESC) AS RN 
-- note 2 
         WHERE long_description = 'Proposal Scope' 
         FROM dbo.Quote_Items 
        ) QI 
         ON QM.idQuote_Main = QI.idQuote_Main 
           AND QI.RN = 1 
WHERE QM.quote_status = 'Won' 
    AND QC.usage_type = 'Quote To' 
; 
  1. это поле не задано так qi_version угадываются, используйте правильное поле
  2. может быть где условием пункта, или может быть использован в последующем условии соединения, влияние размещения изменит результаты, пожалуйста, проверьте оба варианта, чтобы выбрать наиболее подходящий вариант.
Смежные вопросы