如何使用条件加入另一个 table 中的数据子集
How to join to subset of data in another table using criteria
我有一个 table,其中有许多来自不同研究的 inflation 因素,我想将特定因素作为销售数据 table 中的另一列引入。
我收到以下错误:
子查询 returned 超过 1 个值。当子查询跟在 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。
举个例子:
dbo.Inflation
ID Group Year Factor
1 Dog 2010 1.00
1 Dog 2011 1.01
1 Dog 2012 1.02
1 Cat 2010 2.00
1 Cat 2011 2.10
1 Cat 2012 2.20
2 Dog 2010 1.05
2 Dog 2011 1.04
2 Dog 2012 1.03
2 Cat 2010 2.50
2 Cat 2011 2.40
2 Cat 2012 2.30
dbo.Sales
SalesID Year DogSales CatSales TotalSales
1 2010 50,000 25,000 75,000
2 2010 10,000 15,000 25,000
3 2011 75,000 50,000 125,000
4 2012 12,000 10,000 22,000
5 2012 40,000 15,000 55,000
6 2012 40,000 30,000 70,000
我想根据我指定的 ID return Inflation 我的狗和猫的销售因素 table。因此,如果我想对狗因子使用 ID 1 因子,对猫因子使用 ID 2 因子,结果将是这样的:
SalesID Year DogSales CatSales TotalSales Dog_ Cat_
Factor Factor
1 2010 50,000 25,000 75,000 1.00 2.50
2 2010 10,000 15,000 25,000 1.00 2.50
3 2011 75,000 50,000 125,000 1.01 2.40
4 2012 12,000 10,000 22,000 1.02 2.30
5 2012 40,000 15,000 55,000 1.02 2.30
6 2012 40,000 30,000 70,000 1.02 2.30
我正在尝试使用带有内部联接的子查询来创建这个新字段,但它一直出错。
Select distinct
Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales
,(SELECT Inflation.Factor from dbo.Inflation INNER JOIN dbo.Sales on Inflation.Year = Sales.Year where Inflation.ID = 1 and Inflation.Group = 'Dog') as Dog_Factor
,(SELECT Inflation.Factor from dbo.Inflation INNER JOIN dbo.Sales on Inflation.Year = Sales.Year where Inflation.ID = 2 and Inflation.Group = 'Cat') as Cat_Factor
FROM dbo.Sales
这给了我关于 return 多个值的错误,尽管我想加入的只有一组因素出现在 Inflation table 的结果中当我在 where 子句中使用这些相同的条件时。此外,当我将子查询更新为 SELECT TOP 1 而不仅仅是 SELECT 时,table returns 来自正确对应的 Inflation ID 和组的因素但每行仅从 2010 年开始,就好像它没有识别我的 JOIN 标准一样,见下文:
SalesID Year DogSales CatSales TotalSales Dog_ Cat_
Factor Factor
1 2010 50,000 25,000 75,000 1.00 2.50
2 2010 10,000 15,000 25,000 1.00 2.50
3 2011 75,000 50,000 125,000 1.00 2.50
4 2012 12,000 10,000 22,000 1.00 2.50
5 2012 40,000 15,000 55,000 1.00 2.50
6 2012 40,000 30,000 70,000 1.00 2.50
我希望能够根据需要在 ID 和组之间切换,但将年份作为我连接两个 table 的密钥。
请注意,我也尝试在 FROM 语句之后重复加入 Year 的连接语句,但我得到了太多结果的相同错误。我也尝试了外部应用并得到了同样的东西。
如有任何帮助,我们将不胜感激!
您可以加入 inflation table 两次,一次是狗,一次是猫。
SELECT
s.*
, id.factor AS [Dog_Factor]
, ic.factor AS [Cat_Factor]
FROM dbo.sales s
JOIN dbo.inflation id -- Dog
ON id.year = s.year
AND id.[group] = 'Dog'
AND id.id = 1
JOIN dbo.inflation ic -- Cat
ON ic.year = s.year
AND ic.[group] = 'Cat'
AND ic.id = 2
使用内联 sub-query 时,通常需要将其与外部查询相关联,这是通过 WHERE
子句实现的:
Select distinct
s.SalesID
,s.Year
,s.DogSales
,s.CatSales
,s.TotalSales
,(SELECT i.Factor from @Inflation AS i WHERE i.Year = s.Year AND i.ID = 1 and i.[Group] = 'Dog') as Dog_Factor
,(SELECT i.Factor from @Inflation AS i WHERE i.Year = s.Year AND i.ID = 2 and i.[Group] = 'Cat') as Cat_Factor
FROM @Sales AS s
不过,根据数据集的大小,使用两个 JOIN
回到 Sales
而不是相关的 sub-queries.[=17= 可能会获得更好的性能]
使用两个连接 Sales
:
SELECT
s.SalesID,
s.Year,
s.DogSales,
s.CatSales,
s.TotalSales,
d.Factor AS Dog_Factor,
c.Factor AS Cat_Factor
FROM
@Sales AS s
LEFT JOIN
(
SELECT
ID,
[Year],
Factor
FROM
@Inflation
WHERE
ID = 1
AND
[Group] = 'Dog'
) AS d
ON d.Year = s.Year
LEFT JOIN
(
SELECT
ID,
[Year],
Factor
FROM
@Inflation
WHERE
ID = 2
AND
[Group] = 'Cat'
) AS c
ON c.Year = s.Year
结果,两种方式:
+---------+------+----------+----------+------------+------------+------------+
| SalesID | Year | DogSales | CatSales | TotalSales | Dog_Factor | Cat_Factor |
+---------+------+----------+----------+------------+------------+------------+
| 1 | 2010 | 50,000 | 25,000 | 75,000 | 1.00 | 2.50 |
| 2 | 2010 | 10,000 | 15,000 | 25,000 | 1.00 | 2.50 |
| 3 | 2011 | 75,000 | 50,000 | 125,000 | 1.01 | 2.40 |
| 4 | 2012 | 12,000 | 10,000 | 22,000 | 1.02 | 2.30 |
| 5 | 2012 | 40,000 | 15,000 | 55,000 | 1.02 | 2.30 |
| 6 | 2012 | 40,000 | 30,000 | 70,000 | 1.02 | 2.30 |
+---------+------+----------+----------+------------+------------+------------+
另一种方法:
Select
Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales
,MAX(case when Inflation.ID = 1 and Inflation.Group = 'Dog' then Inflation.Factor end) as Dog_Factor
,MAX(case when Inflation.ID = 2 and Inflation.Group = 'Cat'then Inflation.Factor end) as Cat_Factor
FROM dbo.Sales
LEFT JOIN dbo.Inflation ON Inflation.Year = Sales.Year
GROUP BY Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales
我有一个 table,其中有许多来自不同研究的 inflation 因素,我想将特定因素作为销售数据 table 中的另一列引入。
我收到以下错误: 子查询 returned 超过 1 个值。当子查询跟在 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。
举个例子: dbo.Inflation
ID Group Year Factor
1 Dog 2010 1.00
1 Dog 2011 1.01
1 Dog 2012 1.02
1 Cat 2010 2.00
1 Cat 2011 2.10
1 Cat 2012 2.20
2 Dog 2010 1.05
2 Dog 2011 1.04
2 Dog 2012 1.03
2 Cat 2010 2.50
2 Cat 2011 2.40
2 Cat 2012 2.30
dbo.Sales
SalesID Year DogSales CatSales TotalSales
1 2010 50,000 25,000 75,000
2 2010 10,000 15,000 25,000
3 2011 75,000 50,000 125,000
4 2012 12,000 10,000 22,000
5 2012 40,000 15,000 55,000
6 2012 40,000 30,000 70,000
我想根据我指定的 ID return Inflation 我的狗和猫的销售因素 table。因此,如果我想对狗因子使用 ID 1 因子,对猫因子使用 ID 2 因子,结果将是这样的:
SalesID Year DogSales CatSales TotalSales Dog_ Cat_
Factor Factor
1 2010 50,000 25,000 75,000 1.00 2.50
2 2010 10,000 15,000 25,000 1.00 2.50
3 2011 75,000 50,000 125,000 1.01 2.40
4 2012 12,000 10,000 22,000 1.02 2.30
5 2012 40,000 15,000 55,000 1.02 2.30
6 2012 40,000 30,000 70,000 1.02 2.30
我正在尝试使用带有内部联接的子查询来创建这个新字段,但它一直出错。
Select distinct
Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales
,(SELECT Inflation.Factor from dbo.Inflation INNER JOIN dbo.Sales on Inflation.Year = Sales.Year where Inflation.ID = 1 and Inflation.Group = 'Dog') as Dog_Factor
,(SELECT Inflation.Factor from dbo.Inflation INNER JOIN dbo.Sales on Inflation.Year = Sales.Year where Inflation.ID = 2 and Inflation.Group = 'Cat') as Cat_Factor
FROM dbo.Sales
这给了我关于 return 多个值的错误,尽管我想加入的只有一组因素出现在 Inflation table 的结果中当我在 where 子句中使用这些相同的条件时。此外,当我将子查询更新为 SELECT TOP 1 而不仅仅是 SELECT 时,table returns 来自正确对应的 Inflation ID 和组的因素但每行仅从 2010 年开始,就好像它没有识别我的 JOIN 标准一样,见下文:
SalesID Year DogSales CatSales TotalSales Dog_ Cat_
Factor Factor
1 2010 50,000 25,000 75,000 1.00 2.50
2 2010 10,000 15,000 25,000 1.00 2.50
3 2011 75,000 50,000 125,000 1.00 2.50
4 2012 12,000 10,000 22,000 1.00 2.50
5 2012 40,000 15,000 55,000 1.00 2.50
6 2012 40,000 30,000 70,000 1.00 2.50
我希望能够根据需要在 ID 和组之间切换,但将年份作为我连接两个 table 的密钥。
请注意,我也尝试在 FROM 语句之后重复加入 Year 的连接语句,但我得到了太多结果的相同错误。我也尝试了外部应用并得到了同样的东西。
如有任何帮助,我们将不胜感激!
您可以加入 inflation table 两次,一次是狗,一次是猫。
SELECT
s.*
, id.factor AS [Dog_Factor]
, ic.factor AS [Cat_Factor]
FROM dbo.sales s
JOIN dbo.inflation id -- Dog
ON id.year = s.year
AND id.[group] = 'Dog'
AND id.id = 1
JOIN dbo.inflation ic -- Cat
ON ic.year = s.year
AND ic.[group] = 'Cat'
AND ic.id = 2
使用内联 sub-query 时,通常需要将其与外部查询相关联,这是通过 WHERE
子句实现的:
Select distinct
s.SalesID
,s.Year
,s.DogSales
,s.CatSales
,s.TotalSales
,(SELECT i.Factor from @Inflation AS i WHERE i.Year = s.Year AND i.ID = 1 and i.[Group] = 'Dog') as Dog_Factor
,(SELECT i.Factor from @Inflation AS i WHERE i.Year = s.Year AND i.ID = 2 and i.[Group] = 'Cat') as Cat_Factor
FROM @Sales AS s
不过,根据数据集的大小,使用两个 JOIN
回到 Sales
而不是相关的 sub-queries.[=17= 可能会获得更好的性能]
使用两个连接 Sales
:
SELECT
s.SalesID,
s.Year,
s.DogSales,
s.CatSales,
s.TotalSales,
d.Factor AS Dog_Factor,
c.Factor AS Cat_Factor
FROM
@Sales AS s
LEFT JOIN
(
SELECT
ID,
[Year],
Factor
FROM
@Inflation
WHERE
ID = 1
AND
[Group] = 'Dog'
) AS d
ON d.Year = s.Year
LEFT JOIN
(
SELECT
ID,
[Year],
Factor
FROM
@Inflation
WHERE
ID = 2
AND
[Group] = 'Cat'
) AS c
ON c.Year = s.Year
结果,两种方式:
+---------+------+----------+----------+------------+------------+------------+
| SalesID | Year | DogSales | CatSales | TotalSales | Dog_Factor | Cat_Factor |
+---------+------+----------+----------+------------+------------+------------+
| 1 | 2010 | 50,000 | 25,000 | 75,000 | 1.00 | 2.50 |
| 2 | 2010 | 10,000 | 15,000 | 25,000 | 1.00 | 2.50 |
| 3 | 2011 | 75,000 | 50,000 | 125,000 | 1.01 | 2.40 |
| 4 | 2012 | 12,000 | 10,000 | 22,000 | 1.02 | 2.30 |
| 5 | 2012 | 40,000 | 15,000 | 55,000 | 1.02 | 2.30 |
| 6 | 2012 | 40,000 | 30,000 | 70,000 | 1.02 | 2.30 |
+---------+------+----------+----------+------------+------------+------------+
另一种方法:
Select
Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales
,MAX(case when Inflation.ID = 1 and Inflation.Group = 'Dog' then Inflation.Factor end) as Dog_Factor
,MAX(case when Inflation.ID = 2 and Inflation.Group = 'Cat'then Inflation.Factor end) as Cat_Factor
FROM dbo.Sales
LEFT JOIN dbo.Inflation ON Inflation.Year = Sales.Year
GROUP BY Sales.SalesID
,Sales.Year
,Sales.DogSales
,Sales.CatSales
,Sales.TotalSales