簡體   English   中英

從具有多對多關系的多個表中選擇

[英]SELECT From Multiple tables with many to many relations

大家好,我繼承了一個設計不良的數據庫,我需要從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所在的每家商店。 無論如何,無需重新設計數據庫即可解決此問題。

好的,這里有一個完整的問題清單,例如諸如[FrId]等字符字段用作字符串,諸如[address]等保留字用作名稱等。

讓我們把不良的設計問題放在一邊。

首先,我需要創建一個快速的測試環境。 我沒有輸入外鍵,因為不需要該約束即可獲得正確答案。

--
-- 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而非ID上具有主鍵(PK)。 我不明白為什么會有重復。

但是,下面的查詢通過分組將其刪除。 我更改了Jack 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;

正確的輸出如下。

在此處輸入圖片說明

如果我是正確的,請刪除重復項並更改主鍵。

變更要求

好的,您要在同一張桌子中放置兩個或多個所有者。

下面使用子查詢將所有者列表組合為一個字符串。 另一種方法是擁有一個稱為主要所有者的標志。 選擇該名稱作為顯示名稱。

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

這是第二個查詢的輸出。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM