假设我有两个表格,结构如下:
表人:
---------------------------------------------------
| Pepole |ClothBrandId | ShoeBrandId | HatBrandId|
---------------------------------------------------
| Jo | 1 | 2 | 3 |
---------------------------------------------------
表品牌:
-------------------------
| BrandId |BrandName |
-------------------------
| 1 | NBrand |
-------------------------
| 2 | ABrand |
-------------------------
| 3 | PBrand |
-------------------------
我想要的是使用T-SQL生成如下集:
---------------------------------------------------------
| Pepole |ClothBrandName | ShoeBrandName | HatBrandName|
---------------------------------------------------------
| Jo | NBrand | ABrand | PBrand |
---------------------------------------------------------
目前,我认为select语句中的子查询可以解决这个问题:
SELECT
People,
SELECT BrandName as ClothBrandName FROM Brand WHERE BrandId=ClothBrandId,
SELECT BrandName as ShoeBrandName FROM Brand WHERE BrandId=ShoeBrandId,
SELECT BrandName as HatBrandName FROM Brand WHERE BrandId=HatBrandId
FROM
People
但我认为这不是一个有效的解决方案。 另一个是使用UNPIVOT然后是PIVOT。这将很难读。 还有其他适当的方法吗?
答案 0 :(得分:2)
三个简单的连接将起作用
Select p.People,
c.BrandName ClothBrandName,
s.BrandName ShoeBrandName,
h.BrandName HatBrandName
From People p
Join Brand c On c.BrandId = p.ClothBrandId
Join Brand s On s.BrandId = p.ShoeBrandId
Join Brand h On h.BrandId = p.HatBrandId
但请记住,SQL查询处理器不知道来自联接与子查询...解析器(读取您的SQL并将其转换为缓存计划)必须了解这一点,但在实际的查询引擎中只有三个各种连接,查询优化器根据数据统计(和其他因素)从这三种连接中选取。无论是将SQL表示为连接还是作为相关子查询,都不能控制查询引擎使用这三种连接类型中的哪一种。通常,如果您同时执行这两个版本,并且它们在逻辑上是等效的,那么show query plan将是相同的。
答案 1 :(得分:1)
正确的查询如下:
SELECT p.*,
(SELECT BrandName FROM Brand b WHERE b.BrandId = p.ClothBrandId) as ClothBrandName,
(SELECT BrandName FROM Brand b WHERE b.BrandId = p.ShoeBrandId) as ShoeBrandName,
(SELECT BrandName FROM Brand b WHERE b.BrandId = p.HatBrandId) as HatBrandName
FROM People p;
我添加了表别名。当使用多个表时,您应该努力使用表别名,以便阅读查询的人(包括您自己)知道列的来源。
这与执行left outer join
一样合理,这实际上是另一种选择。请注意,这假设Brand(BrandId)
是唯一的或主键。否则,您可能会在查询中获得多行和错误。
答案 2 :(得分:1)
我会选择三个连接而不是子查询:
SELECT People,
c.BrandName AS ClothBrandName,
s.BrandName AS ShoeBrandName,
h.BrandName AS HatBrandName
FROM People AS p
LEFT JOIN Brand AS c
ON c.BrandID = p.ClothBrandId
LEFT JOIN Brand AS s
ON s.BrandID = p.ShoeBrandId
LEFT JOIN Brand AS h
ON h.BrandID = p.HatBrandId;
<强> Example on SQL Fiddle 强>
如果People
中的字段不可为空,则可以将左连接更改为内连接。
答案 3 :(得分:1)
这是另一种选择 - 三次加入Table Brand:
SELECT People, CB.BrandName, SB.BrandName, HB.BrandName
FROM People
LEFT JOIN Brand AS CB on BrandId = ClothBrandId
LEFT JOIN Brand AS SB on BrandId = ShoeBrandId
LEFT JOIN Brand AS HB on BrandId = HatBrandId
只有在您完全确定所有三个品牌都会出现在表格中时才将其更改为“加入”。
答案 4 :(得分:1)
我会在Brand
SELECT
p.*,
cb.BrandName AS ClothBrandHane,
sb.BrandName AS ShoeBrandName,
hb.BrandName AS HatBrandName
FROM People p,
JOIN Brand cb ON cb.BrandID = p.ClothBrandID
JOIN Brand sb ON sb.BrandID = p.ShoeBrandID
JOIN Brand hb ON hb.BrandID = p.HatBrandID