2014-01-13 2 views
0

Привет всем Я inherirted плохо спроектированный базы данных, и мне нужно, чтобы получить некоторую информацию из 3 таблицвыбрать один из нескольких таблиц со многими ко многим отношений

Франчайзинг

Id(Int, PK) 
    FrID (varchar(50)) 
    FirstName (varchar(50)) 
    LastName (varchar(50)) 

магазин

Id (Int, PK) 
FrID (varchar(50)) 
StoreNumber (varchar(50)) 
StoreName 
Address 

Ценообразование

Id (int, PK) 
StoreNumber (varchar(50)) 
Price1 
Price2 
Price3 

и данные

ID, FrID ,FirstName,LastName 
1, 10 ,John Q , TestCase 
2, 10 ,Jack Q , TestCase 
3, 11 ,Jack Q , TestCase 


ID, FrID, StoreNumber , StoreName , Address 
10, 10 , 22222  , TestStore1, 123 Main street 
11, 10 , 33333  , TestStore2, 144 Last Street 
12, 10 , 44444  , TestStore2, 145 Next Street 
13, 11 , 55555  , Other Test, 156 Other st 


ID, StoreNumber, Price1, Price2, Price3 
1, 22222  , 19.99, 20.99 , 30.99 
2, 33333  , 19.99, 20.99 , 30.99 
3, 44444  , 19.99, 20.99 , 30.99 
4, 55555  , 19.99, 20.99 , 30.99 

Вот что я сделал

SELECT F.FirstName,F.LastName,F.FrID , S.StoreNumber,S.StoreName,S.Address, 
     P.Price1,P.Price2,P.Price3 
FROM Franchisee F 
JOIN Store S on F.FrID = S.FrID 
JOIN Pricing P on P.StoreNumber = S.StoreNumber 

Эта часть работы, но я в конечном итоге с большим количеством дублей, например Джек Q получает в списке для его магазина плюс каждый магазин, в который Джон Q включен. Есть ли все равно, чтобы исправить это без редизайна базы данных.

+1

но Джон и Джек оба принадлежат к '10' франшизы ид .. поэтому их магазины, кажется, являются общими. –

+1

Дайте нам образец данных, которые вы ожидаете получить. Так как ваши данные структурированы, в настоящее время один запрос будет создавать дубликаты. –

+0

@Gaby, Спасибо за редактирование, я заметил и попытался исправить это, но вы избили меня до него. – Ksliman

ответ

1

Хорошо, есть целый список прачечного вопросов, таких как характер таких областях, как [Фрид] используется в качестве строк, зарезервированные слова, такие как [адрес] используется в качестве имени и т.д.

Давайте соберем плохо проблемы дизайна.

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

-- 
-- Setup test tables 
-- 


-- Just playing 
use Tempdb; 
go 

-- drop table 
if object_id('franchise')> 0 
drop table franchise; 
go 

-- create table 
create table franchise 
( 
    Id int primary key, 
    FrID varchar(50), 
    FirstName varchar(50), 
    LastName varchar(50) 
); 

-- insert data 
insert into franchise values 
(1, 10, 'John Q', 'TestCase'), 
(2, 10, 'Jack Q', 'TestCase'), 
(3, 11, 'Jack Q', 'TestCase'); 

-- select data 
select * from franchise; 
go 


-- drop table 
if object_id('store')> 0 
drop table store; 
go 

-- create table 
create table store 
( 
    Id int primary key, 
    FrID varchar(50), 
    StoreNumber varchar(50), 
    StoreName varchar(50), 
    Address varchar(50) 
); 

-- insert data 
insert into store values 
(10, 10, 22222, 'TestStore1', '123 Main street'), 
(11, 10, 33333, 'TestStore2', '144 Last Street'), 
(12, 10, 44444, 'TestStore2', '145 Next Street'), 
(13, 11, 55555, 'Other Test', '156 Other Street'); 

-- select data 
select * from store; 
go 


-- drop table 
if object_id('pricing')> 0 
drop table pricing; 
go 

-- create table 
create table pricing 
( 
    Id int primary key, 
    StoreNumber varchar(50), 
    Price1 money, 
    Price2 money, 
    Price3 money 
); 


-- insert data 
insert into pricing values 
(1, 22222, 19.99, 20.99 , 30.99), 
(2, 33333, 19.99, 20.99 , 30.99), 
(3, 44444, 19.99, 20.99 , 30.99), 
(4, 55555, 19.95, 20.95 , 30.95); 

-- select data 
select * from pricing; 
go 

Основной проблемой является то, что таблица франшиза должна иметь первичный ключ (PK) на Фрид, а не Id. Я не понимаю, почему есть дубликаты.

Однако нижеприведенный запрос удаляет их путем группировки. Я изменил данные о ценах для Джека Q, чтобы показать, что это другая запись.

-- 
-- Fixed Query - Version 1 
-- 

select 
    f.FirstName, 
    f.LastName, 
    f.FrID, 
    s.StoreNumber, 
    s.StoreName, 
    s.Address, 
    p.Price1, 
    p.Price2, 
    p.Price3 
from 

-- Remove duplicates from francise 
(
select 
    LastName, 
    FirstName, 
    Max(FrID) as FrID 
from 
    franchise 
group by 
    LastName, 
    FirstName 
) as f 

join store s on f.FrID = s.FrID 
join pricing p on p.StoreNumber = s.StoreNumber; 

Правильный выход ниже.

enter image description here

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

Изменить Требования

Хорошо, вы помещаете двух или более владельцев в той же таблице.

Ниже приведен вспомогательный запрос для объединения списка владельцев в одну строку. Другой способ - иметь флаг, называемый основным владельцем. Выберите это как отображаемое имя.

-- 
-- Fixed Query - Version 2 
-- 

select 
    f.OwnersList, 
    f.FrID, 
    s.StoreNumber, 
    s.StoreName, 
    s.Address, 
    p.Price1, 
    p.Price2, 
    p.Price3 
from 

-- Compose owners list 
(
    select 
    FrID, 
    (
    SELECT FirstName + ' ' + LastName + ';' 
    FROM franchise as inner1 
    WHERE inner1.FrID = outer1.FrID 
    FOR XML PATH('') 
) as OwnersList 
    from franchise as outer1 
    group by FrID 
) as f (FrId, OwnersList) 
join store s on f.FrID = s.FrID 
join pricing p on p.StoreNumber = s.StoreNumber 

Вот результат второго запроса.

enter image description here

+0

Спасибо, что мне было нужно, я буду рекомендовать, чтобы этот db был перепроектирован и ради бога нанял dba :-) – Ksliman

+0

Это еще лучше, как всегда Jack Q под FRID 10 владеет только одним магазином 44444, поэтому листинг он как совладелец других был бы неправильным. В идеале я хотел бы перечислить John Q для всех его магазинов, а затем John Q для магазина 44444, а затем Jack Q для магазина 44444, а затем Store 55555, возможно ли это? – Ksliman

+0

Но эта связь не сохраняется в модели базы данных. У вас есть Джон Q и Джек Q, связанные с франшизой 10. Вы должны изменить модель данных, чтобы отразить эту взаимосвязь. Удалите FrID из таблицы франшизы. Создайте таблицу прав собственности, которая имеет следующие (идентификатор франшизы, FrId, идентификатор магазина). Теперь вы можете детализировать право собственности. –

Смежные вопросы