Какой самый эффективный способ создания этого отчета? - PullRequest
2 голосов
/ 16 декабря 2011

Дана таблица (daily_sales) с, скажем, 100k строками следующих данных / столбцов:

id    rep   sales  date  
1     a     123    12/15/2011  
2     b     153    12/15/2011  
3     a      11    12/14/2011  
4     a     300    12/13/2011  
5     a     120    12/12/2011  
6     b     161    11/15/2011  
7     a       3    11/14/2011  
8     c      13    11/14/2011  
9     c      44    11/13/2011  

Какой самый эффективный способ написания отчета (полностью в SQL), показывающего две самые последние записи (rep, sales, date) для каждого имени, поэтому вывод будет:

a  123  12/15/2011  
a   11  12/14/2011  
b  153  12/15/2011  
b  161  11/15/2011  
c   13  11/14/2011  
c   44  11/13/2011  

Спасибо!

Ответы [ 3 ]

2 голосов
/ 16 декабря 2011

К вашему сведению, ваш пример использует в основном зарезервированные слова и делает ужасным для нас попытки запрограммировать против.Если у вас есть настоящие столбцы таблицы, дайте их нам.Это postgres:

select name,value, max(date)
from the_table_name_you_neglect_to_give_us
group by 1,2

Это даст вам список имени, значения, максимума (даты) ... хотя я должен спросить, зачем давать нам столбец с именем value, если он не изменяетсяв примере?

Допустим, у вас есть столбец идентификатора ... мы будем согласовываться с вашей схемой и назовем его 'ID' ...

 select b.id from
(select name,value, max(date) date
from the_table_name_you_neglect_to_give_us
group by 1,2) a
inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value and a.date = b.date

Это даетсписок всех идентификаторов, которые являются максимальными ... положить его вместе:

select name,value, max(date)
from the_table_name_you_neglect_to_give_us
group by 1,2

объединение всех

select name,value, max(date)
from the_table_name_you_neglect_to_give_us
where id not in
(select b.id from
(select name,value, max(date) date
from the_table_name_you_neglect_to_give_us
group by 1,2) a
inner join the_table_name_you_neglect_to_give_us b on a.name=b.name and a.value=b.value      and a.date = b.date)

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

1 голос
/ 16 декабря 2011

Если я понимаю, что вы имеете в виду ... Тогда это МОЖЕТ быть полезным:

SELECT main.name, main.value, main.date 
FROM tablename AS main
LEFT OUTER JOIN tablename AS ctr
    ON main.name = ctr.rname
    AND main.date <= ctr.rdate
GROUP BY main.name, main.date
HAVING COUNT(*) <= 2
ORDER BY main.name ASC, main.date DESC

Я знаю, что SQL короче, чем другие посты, но сначала попробуйте ...

1 голос
/ 16 декабря 2011

Для MySQL, объяснено в @ блоге Quassnoi , индекс на (name, date) и использование этого:

SELECT  t.*
FROM    (
        SELECT  name,
                COALESCE(
                (
                SELECT  date
                FROM    tableX ti
                WHERE   ti.name = dto.name
                ORDER BY
                        ti.name, ti.date DESC
                LIMIT 1 
                OFFSET 1                      --- this is set to 2-1 
                ), CAST('1000-01-01' AS DATE)) AS mdate
        FROM    (
                SELECT  DISTINCT name
                FROM    tableX dt
                ) dto
        ) tg
        , tableX t
WHERE   t.name >= tg.name
  AND   t.name <= tg.name
  AND   t.date >= tg.mdate
...