SQL Server, как узнать, изменилось ли значение - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть таблица с тремя столбцами:

Date, Symbol, Rankings

Как можно перечислить все символы, чей ранг изменился со вчерашнего дня на сегодняшний день?

Я могу легко получить сегодняшние значения:

SELECT TOP (1000) 
    [date], [symbol], [ranking]
FROM 
    [Rankings].[dbo].[Rankings]
WHERE
    CONVERT(VARCHAR(10), date, 102) = CONVERT(VARCHAR(10), GETDATE(), 102)
ORDER BY 
    symbol DESC

Ответы [ 3 ]

0 голосов
/ 24 сентября 2019

Можно GROUP BY [symbol] и с условием min(ranking), не равным max(ranking)

SELECT
    [symbol],
    MAX(CASE WHEN [date] = CONVERT(date, getdate() - 1) THEN [ranking] END) AS yesterday,
    MAX(CASE WHEN [date] = CONVERT(date, getdate()) THEN [ranking] END) AS today
FROM 
    [Rankings]
WHERE
    [date] >= CONVERT(date, getdate() - 1)
AND [date] <= CONVERT(date, getdate())
GROUP BY 
    [symbol]
HAVING  
    MIN([ranking])  <> MAX([ranking])
ORDER BY 
    [symbol] DESC
0 голосов
/ 24 сентября 2019

Я попробовал приведенный ниже код в SQL Server.Оно работает.Преимущество подхода, представленного ниже, состоит в том, что он позволяет избежать использования функций в предложении WHERE, что приводит к возможным запросам.Если столбец Date имеет правильный индекс, приведенный ниже запрос даст хорошую производительность.

CREATE TABLE #rankings(symbol CHAR(10), [date] DATETIME, RANKING INT);

INSERT INTO #rankings VALUES ('MSFT','20190922', 1), ('MSFT','20190923',2), ('AMZN', '20190922', 3), ('AMZN','20190923',3);

DECLARE @todayStart DATETIME = CAST(GETDATE() AS DATE)
DECLARE @yesterDayStart DATETIME = DATEADD(DAY,-1,@todaystart)
SELECT @todayStart, @yesterDayStart


SELECT today.symbol, yesterday.ranking, today.ranking
FROM (SELECT * FROM #Rankings AS today WHERE today.date >= @todayStart) AS today
JOIN (SELECT * FROM #Rankings AS yesterday WHERE yesterday.date >= @yesterdayStart AND yesterday.date < @todayStart) AS yesterday
ON today.symbol = yesterday.symbol 
WHERE today.ranking <> yesterday.ranking
0 голосов
/ 24 сентября 2019

Примерно так

  SELECT TOP (1000) r1.[date]
     ,r1.[symbol]
     ,r1.[ranking]
  FROM [Rankings].[dbo].[Rankings] r1
  INNER JOIN [Rankings].[dbo].[Rankings] r2 ON (
      r1.symbol = r2.symbol
      AND DateAdd(dd, 1, CONVERT(date, r1.date)) = CONVERT(date, r2.date)
      AND r1.ranking != r2.ranking
      )
  order by r1.symbol desc

Обратите внимание, что я делаю сравнение дат, а не строковое представление сравнения дат

...