Вычитание одной строки данных от другого в SQL

Если вы предпочитаете короткие и сжатые решения без разветвлений и массивов, вот мое предпочтительное решение.

Обычный квартал:

public static int GetQuarter(this DateTime date)
{
    return (date.Month + 2)/3;
}

Квартал финансового года:

public static int GetFinancialQuarter(this DateTime date)
{
    return (date.AddMonths(-3).Month + 2)/3;
}

Целочисленное деление усекает десятичные дроби, давая вам целочисленный результат. Поместите методы в статический класс, и у вас будет метод расширения, который будет использоваться следующим образом:

date.GetQuarter()
date.GetFinancialQuarter()

См. dotnetfiddle

.

12
задан Cade Roux 27 May 2009 в 17:36
поделиться

7 ответов

Это может вам помочь (в некоторой степени).


select a.id, a.length, 
coalesce(a.length - 
    (select b.length from foo b where b.id = a.id + 1), a.length) as diff
from foo a

13
ответ дан 26 October 2019 в 08:37
поделиться

Ура !!! это помогает:

SELECT  f.id, f.length, 
    (f.length - ISNULL(f2.length,0)) AS diff
FROM foo f
LEFT OUTER JOIN foo f2
ON  f2.id = (f.id +1)

Пожалуйста, проверьте и другие случаи, это работает для значений, которые вы опубликовали! Обратите внимание, что это для SQL Server 2005

6
ответ дан 26 October 2019 в 08:37
поделиться

Значит, они просто упорядочены от наибольшего к наименьшему?

SELECT f.id, f.length, (f.length - ISNULL(t.length, 0)) AS difference
FROM foo AS f
LEFT JOIN (
    SELECT f1.id
        ,MAX(f2.length) as length
    FROM foo AS f1
    INNER JOIN foo AS f2
        ON f1.length > f2.length
    GROUP BY f1.id
) AS t -- this is the triangle
    ON t.id = f.id

Вы можете использовать COALESCE (или IFNULL ) вместо ISNULL ] для MySQL.

2
ответ дан 26 October 2019 в 08:37
поделиться

​​Что насчет чего-то вроде этого:

SELECT T2.ID, T2.[Length], T2.[Length]-T1.[Length] AS 'Difference'
FROM Foo AS T1 RIGHT OUTER JOIN Foo AS T2 ON ( T1.ID = (T2.ID-1) )
ORDER BY T1.ID
1
ответ дан 26 October 2019 в 08:37
поделиться
Select f1.id, f1.seqnum, f2.seqnum, f1.length, f2.length, f1.length-f2.length 

From (

Select Id, length, row_number(order by length) 'seqnum'
From
foo

) f1

Inner join (

Select 
Id, length, row_number(order by length) 'seqnum' from foo union select 0, 0, 0

) f2 

On f1.seqnum = f2.seqnum + 1

Order by f1.length desc
1
ответ дан 26 October 2019 в 08:37
поделиться

edit: исправлено при повторном чтении Q (неправильно понято)

SELECT f.id, 
       f2.id, 
       f.length, 
       f2.length, 
       (f.length -f2.length) AS difference
FROM foo f, 
     foo f2 
where f2.id = f.id+1

id был неоднозначным

edit: note: проверено в mysql 5.0

1
ответ дан 26 October 2019 в 08:37
поделиться

У меня была такая проблема, и было интересно посмотреть на ваши решения. Мне кажется странным, что такая обычная жизненная проблема так сложна в SQL. Поскольку мне нужны значения только для отчета, я выбрал совершенно другое решение. Я использую Ruby on Rails в качестве front end моей базы данных sqlite3, и просто сделал вычитание в представлении следующим образом:

В вашем контроллере ruby есть объектная переменная @foo, которая хранит строки, возвращенные вашим запросом.

В представлении просто сделайте

<table border=1>
  <tr>
    <th>id</th>
    <th>length</th>
    <th>difference</th>
  </tr>

<% for i in 0..@foo.length-1 do %>
  <tr>
    <td><%=h @foo[i].id %></td>
    <td><%=h @foo[i].length %></td>
    <td><% if (i==@foo.length-1) then %>
        <%=  @foo[i].length %>
      <% else %>
        <%= @foo[i+1].length.to_i - @foo[i].length.to_i %>
      <% end %>
    </td>
  </tr>
<% end %>
</table>

Кажется, это более надежно, чем SQL-решения.

0
ответ дан 26 October 2019 в 08:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: