2016-08-13 3 views
0

Я пытаюсь определить, имеет ли смысл мой текущий дизайн. У меня есть таблица цен, которая всегда будет иметь значение по умолчанию для данного продукта (ProductId). В зависимости от нескольких условий цена может быть перезаписана.DB Design - переопределяющие значения

Учитывая эту таблицу:

table & data

Я хотел бы получить соответствующие цены на основе данного города, округа, штата или по умолчанию. Это несколько надуманно, поскольку тип и приоритет представляют одно и то же и, вероятно, будут ограничены int и индексированы (нет необходимости в строках). Я использую INT, потому что это позволяет мне сортировать и определять приоритеты, какой из них выбрать из TOP внутреннего запроса. Используя этот SQL:

SELECT DISTINCT ProductId, prices.Price 
FROM [CCC].[Prices] p CROSS APPLY 
(
    SELECT TOP 1 Price 
    FROM [CCC].[Prices] p2 
    WHERE p.ProductId = p2.ProductId 
    AND (Type = 'Default' 
     OR (Type = 'City' AND TypeId = 553) 
     OR (Type = 'State' AND TypeId = '4')) 
    ORDER BY [Priority] DESC 
) prices 

Gets мне именно то, что я ищу:

enter image description here


Два метода я рассматриваю являются:

Все в коде приложения (имея все доступные значения, а затем исходя из нулевых значений, найдите наиболее подходящую цену.

В SQL (продемонстрировано выше), взяв верхнее значение, упорядоченное по приоритету в desc И в SQL с использованием креста применим для получения всех цен (по сравнению с одной записью). Coalesce (адресация ответа) также является решением, но coalesce может быть экспансивным, который я нашел в прошлом. Я предпочитаю эту версию.

Есть ли другие методы или узоры, которые я должен учитывать?

+0

Изменить свой вопрос и предоставить образцы данных и желаемые результаты. –

ответ

0

Если вы собираетесь использовать cross apply, вы можете выполнять работу на SQL Server. Что-то, как это один подход:

select t.*, p.price 
from t cross join 
    (select 
     from pricing p 
     where p.productid = t.productid and 
      (p.city = t.city or 
      p.county = t.county and p.city is null or 
      p.state = t.state and p.county is null and t.county is null or 
      p.state is null 
      ) 
     order by (case when p.city is not null then 1 
        when p.county is not null then 2 
        when p.state is not null then 3 
        else 4 
       end) 
    ) p 
0

Если шаблон города, округа, штата, по умолчанию исправить, вы cuold сделать это внешних соединений и слипаются, что-то вроде этого:

select t.*, coalesce(city.price, county.price, state.price, defaulttab.price) as price 
from t left outer join citytab as city t.productid = city.productid 
              and on t.city = city.city 
     left outer join countytab as county on t.productid = county.productid 
              and t.county = county.county 
     left outer join statetab as state on t.productid = state.productid 
              and t.state = state.state 
     join defautlttab on t.productid = defaulttab.productid 
+0

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