Как я могу использовать Group By (вместо самостоятельных объединений), чтобы получить правильные данные (включен конкретный пример) - PullRequest
0 голосов
/ 09 октября 2009

Глядя на связанные вопросы, я не думаю, что этот конкретный вопрос был задан, так что вот так.

У меня была ситуация, когда я трижды объединял таблицы, чтобы получить разные данные на основе дат.

Это заняло слишком много времени, поэтому, пытаясь оптимизировать, я переписал его, используя группу, как определено здесь: http://weblogs.sqlteam.com/jeffs/jeffs/archive/2007/06/12/60230.aspx

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

SELECT
 upc,
 MAX(CASE WHEN ip_start_date <= GETDATE() THEN ip_unit_price END) AS retail_amount,
 MAX(CASE WHEN ip_start_date <= GETDATE() THEN ip_price_multiple END) AS retail_multiplier_num,    
 MAX(CASE WHEN ip_start_date BETWEEN GETDATE() AND DATEADD(ww,1,GETDATE()) THEN ip_unit_price END) AS retail_amt_nxt_wk,
 MAX(CASE WHEN ip_start_date BETWEEN GETDATE() AND DATEADD(ww,1,GETDATE()) THEN ip_price_multiple END) AS retail_multipler_num_nxt_wk,
 MAX(CASE WHEN ip_start_date BETWEEN DATEADD(ww,1,GETDATE()) AND DATEADD(ww,2,GETDATE()) THEN ip_unit_price END) AS retail_amt_wk_after_nxt,
 MAX(CASE WHEN ip_start_date BETWEEN DATEADD(ww,1,GETDATE()) AND DATEADD(ww,2,GETDATE()) THEN ip_price_multiple END) AS retail_multiplier_num_wk_after_nxt
FROM 
 items AS im WITH (NOLOCK)
  retails AS ip WITH (NOLOCK)
   ON im.ID = ip.ID
GROUP BY
 upc 

Итак, глядя на первую строчку, я получаю максимальную розничную продажу с датой меньше, чем сегодня. Мне на самом деле нужен самый последний, а не самый большой. Раньше это обрабатывалось подзапросом, который дал мне MAX (start_date) меньше, чем сегодня. Я не могу сделать МАКС в МАКСЕ, по наиболее вероятным причинам. Я думал о LAST, но я не совсем уверен, что последняя запись всегда будет самой последней в нашей системе (новая система).

Кто-нибудь видит решение этой проблемы? BETWEENS работают нормально, MAX Retail в течение этой недели достаточно хорош для оценки. Однако другой должен быть точным.

(Не стесняйтесь редактировать заголовок. Я не смог придумать краткий способ задать это)

1 Ответ

1 голос
/ 09 октября 2009

В SQL Server 2005+:

SELECT  upc, retail_today.*, retail_next_week.*, retail_two_weeks.*
FROM    items im
OUTER APPLY
        (
        SELECT  TOP 1
                ip_unit_price, ip_price_multiple
        FROM    retail ip
        WHERE   ip.ip_start_date <= GETDATE()
                AND ip.id = im.id
        ORDER BY
                ip_start_date DESC
        ) retail_today
OUTER APPLY
        (
        SELECT  TOP 1
                ip_unit_price, ip_price_multiple
        FROM    retail ip
        WHERE   ip.ip_start_date BETWEEN GETDATE() AND DATEADD(ww, 1, GETDATE())
                AND ip.id = im.id
        ORDER BY
                ip_start_date DESC
        ) retail_next_week
OUTER APPLY
        (
        SELECT  TOP 1
                ip_unit_price, ip_price_multiple
        FROM    retail ip
        WHERE   ip.ip_start_date BETWEEN DATEADD(ww, 1, GETDATE()) AND DATEADD(ww, 2, GETDATE())
                AND ip.id = im.id
        ORDER BY
                ip_start_date DESC
        ) retail_two_weeks

В SQL Server 2000:

SELECT  upc,
        (
        SELECT  TOP 1
                ip_price
        FROM    retail ip
        WHERE   ip.ip_start_date <= GETDATE()
                AND ip.id = im.id
        ORDER BY
                ip_start_date DESC
        ) AS ip_price_today,
        (
        SELECT  TOP 1
                ip_price_multiple
        FROM    retail ip
        WHERE   ip.ip_start_date <= GETDATE()
                AND ip.id = im.id
        ORDER BY
                ip_start_date DESC
        ) AS ip_price_multiple_today,
        …
FROM    items im
...