在一个查询中使用两个Select语句以带回所需的数据集

时间:2018-09-11 11:52:13

标签: sql sql-server

请帮助更正此查询。

我正在尝试将TRADE_AMT调回上周(w1),然后调回年份(YTD)。但是查询一直失败,我知道有一个更简单的解决方案,但这不是我要寻找的,因为我想学习使用多个select语句按照第一个Select语句返回一个数据集的想法。

此外,我想按登录ID分组,但是我知道我只能有一个from语句。

这是我的查询:

SELECT login, W1.TRADE_AMT, YTD.TRADE_AMT
FROM 
(SELECT sum(TRADE_AMT) FROM CORPS
    WHERE DATE > 20180903 AND DATE_ID <= 20180910 
    AND REGION = 'London'
    AND Rating = 'High'
    AND LOGIN IN ('ITI1','RAB0','RR12') ) AS W1

UNION ALL

(SELECT sum(TRADE_AMT) FROM CORPS
    WHERE DATE > 20180101 AND DATE_ID < 20180911 
    AND REGION = 'London'
    AND Rating = 'High'
    AND LOGIN IN ('ITI1','RAB0','RR12') ) AS YTD


GROUP BY login

军团表中的采样日期:

Login   Trade_AMT   Date    Rating
ITI1    100   20180509    High
RAB0    150   20180910    High
RR12    25    20180104    High
YTRT    100   20180225    Low
ACE1    123   20180908    Low
ITI1    354   20180903    Low
RAB0    254   20180331    High
RR12    245   20180314    High
RR12    5236  20180505    High

所需结果:

Login       W1_Volume   YTD_Volume
ITI1        100         2000
RAB0        150         2500
RR12        25          3000

4 个答案:

答案 0 :(得分:2)

可以通过登录在子查询组上使用内部联接

    SELECT W1.login, W1.TRADE_AMT, YTD.TRADE_AMT
    FROM 
    (SELECT login, sum(TRADE_AMT) AS TRADE_AMT FROM CORPS
        WHERE DATE > 20180903 AND DATE_ID <= 20180910 
        AND REGION = 'London'
        AND Rating = 'High'
        AND LOGIN IN ('ITI1','RAB0','RR12') 
      GROUP BY LOGIN) AS W1
    LEFT JOIN (
    SELECT login, sum(TRADE_AMT) AS TRADE_AMT FROM CORPS
    WHERE DATE > 20180101 AND DATE_ID < 20180911 
        AND REGION = 'London'
        AND Rating = 'High'
        AND LOGIN IN ('ITI1','RAB0','RR12') 
        GROUP BY LOGIN ) AS YTD ON YTD.LOGIN =  W1.LOGIN 

左联接也显示不匹配的登录值,但是如果需要在周和年之间进行完全匹配的登录,则可以使用内部联接

答案 1 :(得分:1)

根据示例我发现您需要min()的TRADE_AMT用于第一个子查询,但没有正确地获得第二个子查询的聚合函数

SELECT login, W1.TRADE_AMT, YTD.TRADE_AMT
FROM 
(SELECT login,min(TRADE_AMT) as TRADE_AMT  FROM CORPS
    WHERE DATE > '20180903' AND DATE_ID <= '20180910' 
    AND REGION = 'London'
    AND Rating = 'High'
    AND LOGIN IN ('ITI1','RAB0','RR12') 
 group by login) AS W1

  join

(SELECT login, sum(TRADE_AMT) as TRADE_AMT FROM CORPS
    WHERE DATE > '20180101' AND DATE_ID < '20180911' 
    AND REGION = 'London'
    AND Rating = 'High'
    AND LOGIN IN ('ITI1','RAB0','RR12') 
    group by login
 ) AS YTD
on W1.login=YTD.login

答案 2 :(得分:1)

只需使用case表达式进行条件聚合:

SELECT login,
       sum(case when DATE > 20180903 AND DATE_ID <= 20180910 then TRADE_AMT end) W1_Volume, 
       sum(case when DATE > 20180101 AND DATE_ID < 20180911 then TRADE_AMT end) YTD_Volume
FROM CORPS
WHERE REGION = 'London'
  AND Rating = 'High'
  AND LOGIN IN ('ITI1','RAB0','RR12')
GROUP BY login

(可选)您可以将日期条件放回WHERE子句以加快速度:

  AND DATE > 20180101 AND DATE_ID < 20180911 

答案 3 :(得分:1)

最重要的是,当您将内部查询与一个联合放在一起时,您的外部查询就无法选择(W1.something,YTD.something)。它们融合为一个结果集。合并时,必须在结果集中保留“线索”,以弄清行为何有趣:

SELECT [login], TRADE_AMT, amt_type
FROM 
(
  SELECT 
    [login], sum(TRADE_AMT), 'week' as amt_type
  FROM 
    CORPS
  WHERE 
     DATE > 20180903 AND DATE_ID <= 20180910 
     AND REGION = 'London'
     AND Rating = 'High'
     AND [LOGIN] IN ('ITI1','RAB0','RR12') 
  group by 
    [login]

  UNION ALL

  SELECT 
    [login], sum(TRADE_AMT), 'ytd' as amt_type
  FROM 
    CORPS
  WHERE 
    DATE > 20180101 AND DATE_ID < 20180911 
    AND REGION = 'London'
    AND Rating = 'High'
    AND [LOGIN] IN ('ITI1','RAB0','RR12') 
  group by 
    [login]
)

...其中amt_type指示它是来自ytd查询还是来自星期查询。

这是联合查询的问题。您可以旋转结果集,但这是不必要的...除非您只需要特定格式的结果。这取决于消耗结果集的代码。

(也-LOGIN是保留字...可能应该在您不表示保留字的地方用方括号括起来)

按照scaisEdge的回答,您可以使用联接(而不是联合)在每次登录一行上获得结果集,但是我认为您正在尝试找出联合方法。