Как присоединиться к подмножеству данных в другой таблице, используя критерии - PullRequest
1 голос
/ 18 июня 2019

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

Я получаю следующую ошибку: Подзапрос вернул более 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 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 

Это дает мне ошибку при возврате более чем одного значения, несмотря на то, что только группа факторов, к которым я хочу присоединиться, отображается в результатах таблицы инфляции, когда я использую те же критерии в предложении where. Кроме того, когда я обновляю свои подзапросы на SELECT TOP 1 вместо просто SELECT, таблица возвращает факторы из правильного соответствующего 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   

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

Примечание. Я также пытался повторить оператор объединения, присоединяющийся к Году после моего оператора FROM, но я получил ту же ошибку в отношении слишком большого количества результатов. Я также попробовал внешнее применение и получил то же самое.

Любая помощь здесь будет принята с благодарностью!

Ответы [ 3 ]

1 голос
/ 18 июня 2019

Еще один способ сделать это:

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
0 голосов
/ 18 июня 2019

При использовании встроенного подзапроса вам, как правило, необходимо соотнести его с внешним запросом, что вы делаете с помощью предложения 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 s обратно к Sales, а не коррелированные подзапросы.

Используя два соединения к 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 |
+---------+------+----------+----------+------------+------------+------------+
0 голосов
/ 18 июня 2019

Вы можете присоединиться к таблице инфляции дважды, один раз для собак и один раз для кошек.

DEMO

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...