«CSS-подобные» резервные каскадные данные в SQL Server 2005 - PullRequest
2 голосов
/ 14 апреля 2009

Я пытаюсь внедрить систему снижения цены в SQL-сервере. Я хотел бы иметь набор все более специфических цен (например, по регионам, магазинам, складу и т. Д.) Для продукта, которые могут быть или не быть определены, и иметь возможность выбирать наиболее конкретные цены (то есть: один с большинством параметров) в отчете.

Например, у меня могут быть следующие данные:

 Region
--------
   1
   2

 Store  
--------
   1
   2
   3

Product | Region | Store | Price
--------------------------------
  Foo   | NULL   | NULL  |  1.0
  Foo   | 1      | NULL  |  2.0
  Foo   | 1      | 1     |  2.5
  Foo   | 1      | 2     |  2.3

Так что, если бы я хотел узнать цену на продукт Foo ...

  • в регионе 1, магазин 1 = 2,5
  • в области 1, хранилище 3 = 2,0 (хранилище 3 не определено явно в данных, поэтому результат поступает из хранилища NULL для области 1)
  • в области 2, хранилище 4 = 1,0 (область 2 не определена явно в данных, поэтому результат исходит из области NULL)

Ради простоты могу предположить, что Магазин всегда более конкретен, чем регион, и магазин может существовать только в одном регионе.

Схема для этих данных будет выглядеть примерно так:

CREATE TABLE Prices(
    ID      int   IDENTITY(1,1) NOT NULL,
    Product int   NOT NULL,
    Region  int   NULL,
    Store   int   NULL,
    Price   money NOT NULL,
    CONSTRAINT PK_Prices PRIMARY KEY CLUSTERED (ID ASC),
    CONSTRAINT IX_Prices UNIQUE NONCLUSTERED (Product ASC, Region ASC, Store ASC)
)

Помимо обработки этих данных в коде, как я могу запросить в этой таблице список действующих цен для каждого продукта на основе (регион, магазин)?

Ответы [ 4 ]

4 голосов
/ 14 апреля 2009

попробуйте это:
РЕДАКТИРОВАТЬ для всех продуктов, каждый из которых указан один раз, даже если данный регион и магазин не существуют ...

CREATE PROCEDURE GetPrice
     @Region int = null
    ,@Store int = null
AS

SELECT
    Product
        ,Region
        ,Store
        ,Price
    FROM (SELECT
              Product
                  ,Region AS Region
                  ,Store As Store
                  ,Price
                  ,Row_Number() OVER(PARTITION BY Product ORDER BY SortBy,Product,Region,Store,Price) AS RowNumber
              FROM (SELECT 1 AS SortBy,* FROM Prices WHERE (Region = @Region OR @Region IS NULL) AND (Store = @Store OR @Store IS NULL)
                    UNION
                    SELECT 2 AS SortBy,* FROM Prices WHERE (Region = @Region OR @Region IS NULL) 
                    UNION
                    SELECT 3 AS SortBy,* FROM Prices
                   ) Prices
         ) dt
    WHERE RowNumber=1
    ORDER BY Product

GO
2 голосов
/ 14 апреля 2009

Ух ты, ребята, вы слишком стараетесь. Вот простой способ: используйте команду COALESCE, которая принимает первое ненулевое значение.

SELECT COALESCE(st.Price, rg.Price, gn.Price) AS Price
  FROM dbo.Prices gn  /*General price*/
  LEFT OUTER JOIN dbo.Prices rg /*Regional price*/
    ON rg.Product = @Product AND rg.Region = @Region AND rg.Store IS NULL
  LEFT OUTER JOIN dbo.Prices st  /*Store price*/
    ON rg.Product = @Product AND rg.Region = @Region AND rg.Store = @Store
  WHERE gn.Product = @Product
    AND gn.Region IS NULL AND gn.Store IS NULL

Таким образом, вы получите цену магазина, если она не равна нулю, или региональную цену, если она не равна нулю, или общую цену, если все остальное терпит неудачу.

1 голос
/ 14 апреля 2009

Я думаю, что ваша модель данных может быть немного странной. Таблица цен заполняется только для отчета? Я мог бы просмотреть свои таблицы, но если бы мне пришлось использовать эту настройку, я бы сделал что-то вроде этого:

Для цен на товары в указанном регионе (НЕ МАГАЗИН). Используйте этот выбор в sproc, который принимает регион в качестве параметра. Если я все сделал правильно, он вернет цену региона, если она есть, и цену продукта, если ее нет.

Выберите Product, Price из dbo.prices, где (Region = @region) или (region равен NULL, а продукт отсутствует) (выберите продукт из цен, где region = @Region))

Для цен на товары в указанном магазине. Используйте этот выбор в sproc, который принимает хранилище в качестве параметра. Вам также нужно будет пройти в регион или выяснить это из магазина. Если я все сделал правильно, он вернет цену магазина, если она есть, то цена региона, затем цена товара.

Выберите продукт, цену из dbo.prices, где (store = @store) или (store - NULL AND region = @Region, а продукта нет в (выберите продукт из цен, где store = @store) или (store - NULL и region имеет значение NULL, а продукт отсутствует (выберите продукт из цен, где region = @Region))

Чтобы получить цены из нескольких регионов или магазинов, просто выполните одно из указанных выше действий несколько раз (в цикле или курсоре).

0 голосов
/ 14 апреля 2009

Полагаю, это должно сработать (хотя и не пробовал):

select top 1 price
from prices
where product = @product
and isnull(region, @region) = @region
and isnull(store, @store) = @store
order by region desc, store desc

Товар должен иметь не менее 1 записи цен. ORDER BY .. DESC сортирует исходные значения NULL последними.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...