2014-01-13 42 views
0

大家好我已经inherirted一个设计不当的数据库,我需要从3个表从许多多的表的SELECT许多关系

特许经营

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被列为他的商店加上John Q所在的每家商店。无论如何要解决这个问题,重新设计一个数据库。

+1

但约翰和杰克都属于'10'专营ID ..所以他们的商店似乎是共同的。 –

+1

给我们一个您希望找回的数据样本。数据结构化的方式目前只有一个查询会产生重复。 –

+0

@Gaby,感谢您的编辑,我注意到并试图解决它,但是您击败了我。 – Ksliman

回答

1

好了,就有问题,如字符型字段,如整体箩筐[FRID]被用来作为字符串,保留字如[地址]被用作名称等

让我们把坏除了设计问题。

首先,我需要创建一个快速测试环境。我没有放置外键,因为不需要约束来获得正确的答案。

-- 
-- 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 

主要问题是专营表应该有FRID主键(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

感谢这是我需要的,我会建议这个数据库被重新设计,并为上帝的缘故雇用一个dba :-) – Ksliman

+0

这甚至更好,杰克Q如何在FRID 10共同拥有一个商店44444,所以列出他作为其他人的共同所有人将是不正确的。理想情况下,我想列出John Q的所有店铺,然后John Q店铺44444,然后Jack Q店铺44444,然后店铺55555,这甚至有可能吗? – Ksliman

+0

但是这种关系没有存储在数据库模型中。你有John Q和Jack Q与特许经营10有关。你必须改变数据模型以反映这种关系。从表特许权移除FrID。创建一个拥有以下特权的表(特许经营编号,FrId,商店编号)。现在您可以详细了解所有权。 –