Коррелированный подзапрос? извлечение данных из разных столбцов, одной и той же таблицы - PullRequest
0 голосов
/ 18 марта 2019

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

Я рассчитываю получить средние значения для выигрыша Miami Heat по следующим категориям + средние значения потерь New York Knicks для следующих категорий и объединить их в одно среднее.

Так что это мой запрос на Жару, который возвращает именно то, что я хочу

SELECT
    box_score.team_name, 
    ROUND(AVG(eFG),3) eFG,
    ROUND(AVG(OPP_eFG),3) OPP_eFG,
    ROUND(AVG(TOV_PCT),3) TOV_PCT,
    ROUND(AVG(OPP_TOV_PCT),3) OPP_TOV_PCT,
    ROUND(AVG(ORB_PCT),3) ORB_PCT,
    ROUND(AVG(DRB_PCT),3) DRB_PCT,
    ROUND(AVG(FTA_RATE),3) FTA_RATE,
    ROUND(AVG(OPP_FTA_RATE),3) OPP_FTA_RATE
FROM box_score
WHERE team_name = 'Miami Heat' AND WIN_LOSS = 'W' AND game_date < '2019-03-07' 

Я также понес потери за рывки, что также привело к тому, что я хотел

WHERE team_name = 'New York Knicks' AND WIN_LOSS = 'L' AND game_date < '2019-03-07' 

Моя проблема состоит в том, чтобы попытаться объединить два в один запрос, где я получаю средние значения в выигрышах Хита и среднее в потерях Ника. вся эта информация из той же таблицы, и я могу получить информацию о команде из идентификатора или по имени ... Я использую SQLite, если это что-то меняет

Это результат выполнения запроса, по которому я ищу одну строку данных со средним значением ... однако мне бы хотелось, чтобы среднее из этих чисел как в выигрышах в Хай, так и в проигрышах Нникса было объединено в одну строку

Средние в Хит Победы

eFG    OPP_eFG  TOV_PCT  OPP_TOV_PCT  ORB_PCT  DRB_PCT  FTA_RATE  OPP_FTA_RATE
0.603  0.505    0.14     0.126        0.28     0.77     0.235     0.141

Это средние значения потерь в киках

eFG    OPP_eFG  TOV_PCT  OPP_TOV_PCT  ORB_PCT  DRB_PCT  FTA_RATE  OPP_FTA_RATE
0.568  0.602    0.146    0.136        0.225    0.787    0.222     0.235

Я хочу объединить два в 1 среднее для каждой категории

но есть ли способ сделать так, чтобы я получал средние значения для извлечения данных из отдельных столбцов?

В этом случае меня интересует Майами Хит, поэтому у меня есть средние значения выше, но я пытаюсь получить средние значения от Хиты до соответствующей противоположной характеристики для пиков (eFG должен коррелировать с opp_eFG другой команды и т. д.) ... так что в основном я ищу средние значения по следующим параметрам:

Heat eFG и OPP_eFG Knicks

Нагрев OPP_eFG и eFG Knicks

Нагрев TOV_PCT и OPP_TOV_PCT Knicks

Нагрев OPP_TOV_PCT и TOV_PCT Knicks

Нагреть FTA_RATE и OPP_FTA_RATE Knicks

Нагрев OPP_FTA_RATE и FTA_RATE Knicks

все еще надеется получить 1 строку в результате

Ответы [ 3 ]

1 голос
/ 18 марта 2019

В этом ответе предполагается, что вы хотите AVG (нагрев) -AVG (knicks), как в оригинальном сообщении, а не AVG (heatsX ИЛИ knicksY)

Я бы хотел продвинуть Common Table Expressions для этого:

WITH selector_heat as (
SELECT
    box_score.team_name, 
    ROUND(AVG(eFG),3) eFG,
    ROUND(AVG(OPP_eFG),3) OPP_eFG,
    ROUND(AVG(TOV_PCT),3) TOV_PCT,
    ROUND(AVG(OPP_TOV_PCT),3) OPP_TOV_PCT,
    ROUND(AVG(ORB_PCT),3) ORB_PCT,
    ROUND(AVG(DRB_PCT),3) DRB_PCT,
    ROUND(AVG(FTA_RATE),3) FTA_RATE,
    ROUND(AVG(OPP_FTA_RATE),3) OPP_FTA_RATE
FROM box_score
WHERE team_name = 'Miami Heat' AND WIN_LOSS = 'W' AND game_date < '2019-03-07' 
)
, selector_knicks as (
...
)
select H.eFG - K.OPP_eFG as magic_nbr
from selector_heat H 
join selector_knicks K ON (1=1)

Подробнее о синтаксисе здесь: https://www.sqlite.org/lang_with.html но пока игнорируйте «рекурсивные» биты, в этом случае они вам не нужны.

В качестве альтернативы (и с немного другим углом захода на посадку) вы можете использовать предложения Window для агрегирования «на группу», а затем использовать результаты. Больше информации здесь: https://www.sqlite.org/windowfunctions.html#introduction_to_window_functions

Пример:

SELECT  
  team_name, 
  WIN_LOSS,
  ROUND(AVG(eFG) OVER (partition by team_name, win_loss),3) as eFG
  ...
  from box_score
  where game_date < '2019-03-07'

С этим набором результатов у вас есть средние значения для всех команд и комбинаций win_loss. Оберните это в CTE и присоедините к себе на подходящих условиях, например

WITH cte as (SELECT ...)
SELECT H.eFG - K.OPP_eFG as magic_nbr
FROM cte H join cte K 
  ON (H.team_name = 'Miami Heat' 
  AND K.team_name = 'NY Knicks'
  AND H.win_loss = 'W'
  AND K.win_loss = 'L')
1 голос
/ 18 марта 2019

Если вы хотите вычислить средние значения сначала , а затем усреднить их, вы можете использовать два уровня агрегирования:

SELECT ROUND(AVG(eFG), 3) as eFG,
       ROUND(AVG(OPP_eFG), 3) as OPP_eFG,
       ROUND(AVG(TOV_PCT), 3) as TOV_PCT,
       ROUND(AVG(OPP_TOV_PCT), 3) as OPP_TOV_PCT,
       ROUND(AVG(ORB_PCT), 3) as ORB_PCT,
       ROUND(AVG(DRB_PCT), 3) as DRB_PCT,
       ROUND(AVG(FTA_RATE), 3) as FTA_RATE,
       ROUND(AVG(OPP_FTA_RATE), 3) as OPP_FTA_RATE
FROM (SELECT bs.team_name, 
             AVG(eFG) as eFG,
             AVG(OPP_eFG) as OPP_eFG,
             AVG(TOV_PCT) as TOV_PCT,
             AVG(OPP_TOV_PCT) as OPP_TOV_PCT,
             AVG(ORB_PCT) as ORB_PCT,
             AVG(DRB_PCT) as DRB_PCT,
             AVG(FTA_RATE) as FTA_RATE,
             AVG(OPP_FTA_RATE) as OPP_FTA_RATE
      FROM box_score bs
      WHERE game_date < '2019-03-07' AND
            ( (team_name = 'Miami Heat' AND WIN_LOSS = 'W') OR
              (team_name = 'New York Knicks' AND WIN_LOSS = 'L')
            )
     ) bs
0 голосов
/ 18 марта 2019

Одним из решений было бы выполнение всей операции за одно сканирование таблицы (без объединений или подзапросов), используя условное агрегирование :

SELECT  
    box_score.team_name, 
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN eFG          END),3) Heat_eFG,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN eFG          END),3) Knicks_eFG,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN OPP_eFG      END),3) Heat_OPP_eFG,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN OPP_eFG      END),3) Knicks_OPP_eFG,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN TOV_PCT      END),3) Heat_TOV_PCT,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN TOV_PCT      END),3) Knicks_TOV_PCT,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN OPP_TOV_PCT  END),3) Heat_OPP_TOV_PCT,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN OPP_TOV_PCT  END),3) Knicks_OPP_TOV_PCT,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN ORB_PCT      END),3) Heat_ORB_PCT,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN ORB_PCT      END),3) Knicks_ORB_PCT,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN DRB_PCT      END),3) Heat_DRB_PCT,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN DRB_PCT      END),3) Knicks_DRB_PCT,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN FTA_RATE     END),3) Heat_FTA_RATE,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN FTA_RATE     END),3) Knicks_FTA_RATE,
    ROUND(AVG(CASE WHEN team_name = 'Miami Heat'      AND WIN_LOSS = 'W' THEN OPP_FTA_RATE END),3) Heat_OPP_FTA_RATE,
    ROUND(AVG(CASE WHEN team_name = 'New York Knicks' AND WIN_LOSS = 'L' THEN OPP_FTA_RATE END),3) Knicks_OPP_FTA_RATE
FROM box_score
WHERE team_name IN ('Miami Heat', 'New York Knicks') AND game_date < '2019-03-07' 

Вот еще одна версиязапроса, если вы хотите вычислить среднее значение, например, eFG для побед в Майами и OPP_eFG для потерь в Нью-Йорке в одном столбце.Это все еще зависит от условной агрегации.Я также немного упростил логику, переместив условия в предложение WHERE.

SELECT  
    box_score.team_name, 
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN eFG 
        WHEN team_name = 'New York Knicks' THEN OPP_eFG 
    END, 3) Heats_eFG_Knicks_OPP_eFG, 
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN OPP_eFG 
        WHEN team_name = 'New York Knicks' THEN eFG 
    END, 3) Heats_OPP_eFG_Knicks_eFG,
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN TOV_PCT 
        WHEN team_name = 'New York Knicks' THEN OPP_TOV_PCT 
    END, 3) Heats_TOV_PCT_Knicks_OPP_TOV_PCT,
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN OPP_TOV_PCT 
        WHEN team_name = 'New York Knicks' THEN TOV_PCT 
    END, 3) Heats_OPP_TOV_PCT_Knicks_TOV_PCT,
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN FTA_RATE 
        WHEN team_name = 'New York Knicks' THEN OPP_FTA_RATE 
    END, 3) Heats_FTA_RATE_Knicks_OPP_FTA_RATE,
    ROUND(AVG(CASE 
        WHEN team_name = 'Miami Heat'      THEN OPP_FTA_RATE 
        WHEN team_name = 'New York Knicks' THEN FTA_RATE 
    END, 3) Heats_OPP_FTA_RATE_Knicks_FTA_RATE
FROM box_score
WHERE 
    game_date < '2019-03-07' 
    AND (
           ( team_name = 'Miami Heat'      AND win_loss = 'W' )
        OR ( team_name = 'New York Knicks' AND win_loss = 'L') 
    )

Примечание: как прокомментировал wildpasser , вы, вероятно, захотите использовать одинарные кавычки вместодвойные кавычки вокруг буквальных значений (это стандарт SQL).Я глобально все двойные кавычки в исходном запросе в одинарные кавычки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...