SQL多重选择与问题组

时间:2016-02-02 18:14:36

标签: sql sql-server

我有一张表,其中包含工作订单列表,其中包含创建日期和完成日期。我已经在堆栈溢出上找到了一个GROUP BY语句,但它似乎没有产生我预期的结果。我的目标是拥有以下

TERM  |  OPENED  |  CLOSED
----------------------------
01-15  |    432   |  243
02-15  |    543   |  859
03-15  |    102   |  437
04-15  |    153   |  342
...    |    ...   |  ...
01-16  |    175   |  256
02-16  |     55   |   30

这是我正在使用的代码

select COUNT(wo) AS opened FROM wkaw 
WHERE org_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01)
GROUP BY MONTH(org_date) + '-' + YEAR(org_date)

select COUNT(wo) AS closed FROM wkaw 
WHERE cmpl_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01) AND  cmpl_date IS NOT NULL
GROUP BY MONTH(cmpl_date) + '-' + YEAR(cmpl_date)

我最初使用CROSS JOIN尝试将两个语句连接在一起,但它也没有产生预期的结果。我的目标是,我希望最终将其转换为VIEW或存储过程,它将选择过去一年的结果,以便我可以对数据进行趋势分析。

我不太确定从哪里开始。

基于以下响应的更新代码;它向我展示了如何修复我的group by子句,所以我得到了我预期的行数,我只需要弄清楚如何使用join语句。

select MONTH(org_date) + (YEAR(org_date)*100) as dateinfo, COUNT(wo) AS opened FROM wkaw 
WHERE org_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01)
GROUP BY MONTH(org_date) +  (YEAR(org_date)*100)
ORDER BY dateinfo

select MONTH(cmpl_date) + (YEAR(cmpl_date)*100) as dateinfo, COUNT(wo) AS closed FROM wkaw 
WHERE cmpl_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01) AND cmpl_date IS NOT NULL
GROUP BY MONTH(cmpl_date) + (YEAR(cmpl_date)*100)
order by dateinfo

不需要的订单只是使用它来使其更容易阅读

4 个答案:

答案 0 :(得分:1)

对两个查询使用CTE,添加术语列并对其进行完全连接:

WITH
op(count,term) AS (
  SELECT COUNT(*), MONTH(org_date) + '-' + YEAR(org_date) FROM ...
),
cl(count,term) AS (
    SELECT COUNT(*), MONTH(cmpl_date) + '-' + YEAR(cmpl_date) FROM ...
)
SELECT ISNULL(op.term,cl.term) AS term, ISNULL(op.count,0) AS opened, ISNULL(cl.count,0) AS closed
FROM op
FULL JOIN cl ON op.term=cl.term

答案 1 :(得分:1)

<div class="border"></div>    

<强>结果

create table wkaw (wo int, org_date date, cmpl_date date);

insert into wkaw values (1, '2015-02-01', '2015-02-28');
insert into wkaw values (1, '2015-02-01', '2015-02-28');
insert into wkaw values (1, '2015-02-01', '2015-03-31');
insert into wkaw values (1, '2015-12-01', '2015-12-21');
insert into wkaw values (1, '2015-12-01', '2015-12-21');
insert into wkaw values (1, '2015-11-01', '2015-12-21');

select coalesce(x.mth, y.mth) period, coalesce(opened, 0) opened, coalesce(closed, 0) closed from (
 (
    select RIGHT('0' + CAST(MONTH(org_date) AS varchar(2)), 2) + '-' + CAST(YEAR(org_date) AS CHAR(4)) as mth, COUNT(wo) AS opened FROM wkaw 
    WHERE org_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01)
    GROUP BY RIGHT('0' + CAST(MONTH(org_date) AS varchar(2)), 2) + '-' + CAST(YEAR(org_date) AS CHAR(4))
  ) x
  full outer join
  (
    select RIGHT('0' + CAST(MONTH(cmpl_date) AS varchar(2)), 2) + '-' + CAST(YEAR(cmpl_date) AS CHAR(4)) as mth, COUNT(wo) AS closed FROM wkaw 
    WHERE cmpl_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01)
    GROUP BY RIGHT('0' + CAST(MONTH(cmpl_date) AS varchar(2)), 2) + '-' + CAST(YEAR(cmpl_date) AS CHAR(4))
   ) y
   on x.mth = y.mth
 )
order by 1

注意:我在这里没有考虑任何表现。

答案 2 :(得分:0)

最后,使用Shire的回复和Pavel的回复,我能够提出以下SQL代码来生成我正在寻找的结果。我不确定这会如何影响性能,但似乎效果很好。

select o.dateinfo, opened, closed FROM (
select MONTH(org_date) + (YEAR(org_date)*100) as dateinfo, COUNT(wo) AS opened FROM wkaw 
WHERE org_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01)
GROUP BY MONTH(org_date) +  (YEAR(org_date)*100)) o
INNER JOIN (
select MONTH(cmpl_date) + (YEAR(cmpl_date)*100) as dateinfo, COUNT(wo) AS closed FROM wkaw 
WHERE cmpl_date >= DATEFROMPARTS(YEAR(GETDATE())-1,MONTH(GETDATE()),01) AND cmpl_date IS NOT NULL
GROUP BY MONTH(cmpl_date) + (YEAR(cmpl_date)*100)) c
ON o.dateinfo = c.dateinfo
ORDER BY o.dateinfo

感谢绅士的帮助!

干杯, 乔纳森

答案 3 :(得分:0)

使用sql分析函数还有另一种可能性:

WITH c(oterm,cterm) AS
(SELECT MONTH(org_date) + '-' + YEAR(org_date),MONTH(cmpl_date) + '-' + YEAR(cmpl_date) FROM wkaw),
a(term,cterm,opened,closed) AS
(SELECT DISTINCT oterm, cterm, COUNT(*) OVER (PARTITION BY oterm), COUNT(*) OVER (PARTITION BY cterm) FROM c)
SELECT term, opened, closed
FROM a
WHERE term = cterm