Предложение GROUP BY - слишком много результатов - PullRequest
0 голосов
/ 22 марта 2012

У меня проблемы с предложением GROUP BY в MSSQL.

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

Это мой SQL

SELECT idAnalysis, idNotation, max(PublishedTime) AS PublishedTime, Created, 
       T2.Link, T3.Name AS Rec, V.NAME_SECURITY, V.PRICE
FROM Analysis T1
INNER JOIN Templates T2 ON T1.idTemplates = T2.idTemplates 
LEFT JOIN Recommendations T3 ON T1.idRecommendation = T3.idRecommendations
INNER JOIN RFD.dbo.vLiveQuotes V ON T1.idNotation = V.ID_NOTATION
WHERE PublishedTime is not null
      AND
      T2.idTemplates = 4
GROUP BY idNotation, idAnalysis, [Level], Goal, StopLoss, Header, [Resume],
         T2.Name, Created, T2.Link, T3.Name, V.NAME_SECURITY, V.PRICE
ORDER BY PublishedTime DESC

Результат:

25  7239884 Akkumuler   DANSKE BANK A/S DKK10   93
24  7239884 Sælg    DANSKE BANK A/S DKK10   934.500
22  7490572 Sælg    A.P. MOLLER - MAERSK SER`B`DKK1000  43
23  7239884 Hold    DANSKE BANK A/S DKK10   93
18  2027313 Køb GENMAB AS DKK1 (BEARER) 41

Но результат должен быть:

25  7239884 Akkumuler   DANSKE BANK A/S DKK10   93
22  7490572 Sælg    A.P. MOLLER - MAERSK SER`B`DKK1000  43
18  2027313 Køb GENMAB AS DKK1 (BEARER) 41

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Вы группируете по Level, Goal, StopLoss, Header, Resume, T2.Name, но эти столбцы отсутствуют в списке выбора.Удалить их из group by.

1 голос
/ 22 марта 2012

Если я правильно прочитал ваш запрос, вы хотите, чтобы данные из T1, T2 и T3 и только последняя публикация из V. Для сокращения, T1, T2 и T3 будут рассматриваться как одна таблица T. несколько вариантов. Проверьте их и используйте тот, который работает быстрее всего в вашей ситуации.

Использование row_number

select *
from T
inner join 
(
   select ID_NOTATION, V.NAME_SECURITY, V.PRICE, V.PublishedTime
          row_number() over (partition by ID_NOTATION 
                             order by PublishedTime desc) AS RowNumber
     from RFD.dbo.vLiveQuotes V
) V
  ON T.idNotation = V.ID_NOTATION
  and V.RowNumber = 1

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

select *
from T
cross apply
(
   select TOP 1 *
     from RFD.dbo.vLiveQuotes V
    where V.idNotation = T.ID_NOTATION
    order by PublishedTime desc
) V

Если вы ограничены более старым Sql Server, вы можете попробовать это:

select *
from T
inner join 
(
   select * 
     from RFD.dbo.vLiveQuotes V
     inner join
     (
         select ID_NOTATION, max(V.PublishedTime) PublishedTIme
           from RFD.dbo.vLiveQuotes
          group by ID_NOTATION
     ) lastPublishedTime
       on V.ID_NOTATION = lastPublishedTime.ID_NOTATION
       and V.PublishedTime = lastPublishedTime.PublishedTIme
) V
  ON T.idNotation = V.ID_NOTATION

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

ОБНОВЛЕНИЕ: узнал, что PusblishedTime живет в Analysis.

Самое простое - удалить max / group by, добавить производную таблицу idNotations и max (Опубликованное время) и вернуться в Analysis:

SELECT idAnalysis, t1.idNotation, T1.PublishedTime AS PublishedTime, Created, 
       T2.Link, T3.Name AS Rec, V.NAME_SECURITY, V.PRICE
FROM Analysis T1
INNER JOIN Templates T2 ON T1.idTemplates = T2.idTemplates 
LEFT JOIN Recommendations T3 ON T1.idRecommendation = T3.idRecommendations
INNER JOIN RFD.dbo.vLiveQuotes V ON T1.idNotation = V.ID_NOTATION
inner join
(
  select idNotation, max(V.PublishedTime) PublishedTIme
    from Analysis
   group by idNotation
) lastPublishedTime
  on T1.idNotation = lastPublishedTime.idNotation
  and t1.PublishedTime = lastPublishedTime.PublishedTime
WHERE PublishedTime is not null
      AND
      T2.idTemplates = 4
ORDER BY PublishedTime DESC

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

...