2017-03-09 5 views
0

私は以下の2つのテーブルを持っています。mysqlクエリの2つの日付間のすべての会計年度リストを検索したい

CREATE TABLE IF NOT EXISTS `order` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `loc_id` bigint(20) NOT NULL, 
    `orderdate` date NOT NULL, 
    `cash` double NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ; 

INSERT INTO `order` (`id`, `loc_id`, `orderdate`, `cash`) VALUES 
(1, 1, '2012-02-09', 120), 
(2, 2, '2011-07-21', 100), 
(3, 3, '2005-04-25', 180), 
(4, 1, '2008-12-01', 300), 
(5, 2, '2014-07-21', 100), 
(6, 3, '2004-04-25', 180), 
(7, 1, '1998-12-01', 300); 

他の一つは、私は会計年度賢明なすべての領域のための現金のすべての合計を知りたい

CREATE TABLE IF NOT EXISTS `location` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `loc_name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; 

INSERT INTO `location` (`id`, `loc_name`) VALUES 
(1, 'region1'), 
(2, 'region2'), 
(3, 'region3'); 

です。

だから私のselect文は次のようである:

SELECT 
    CASE 
     WHEN MONTH(a.orderdate) <4 THEN CONCAT(YEAR(a.orderdate)-1,'-',YEAR(a.orderdate)) 
    ELSE 
     CONCAT(YEAR(a.orderdate),'-',YEAR(a.orderdate)+1) END AS Fiscalyear, 
SUM(a.cash),b.loc_name 
FROM order as a JOIN location b on a.loc_id=b.id 
WHERE YEAR(a.orderdate) BETWEEN 2005 AND 2012 
GROUP BY Fiscalyear,a.loc_id 

その出力は次のようになります。

Fiscalyear | SUM(a.cash) | loc_name 
2005-2006  |180   | region3  
2008-2009  |300   | region1  
2011-2012  |120   | region1  
2011-2012  |100   | region2 

しかし、私は実際に必要とする:

Fiscalyear | SUM(a.cash) | loc_name 
2005-2006  |0    | region1  
2005-2006  |0    | region2  
2005-2006  |180   | region3  
2006-2007  |0    | region1 
2006-2007  |0    | region2  
2006-2007  |0    | region3  
2007-2008  |0    | region1  
2007-2008  |0    | region2  
2007-2008  |0    | region3  
2008-2009  |300   | region1  
2008-2009  |0    | region2  
2008-2009  |0    | region3  
2009-2010  |0    | region1  
2009-2010  |0    | region2  
2009-2010  |0    | region3  
2010-2011  |0    | region1 
2010-2011  |0    | region2  
2010-2011  |0    | region3 
2011-2012  |120   | region1  
2011-2012  |100   | region2 
2011-2012  |0    | region3 

あなたは、単一のクエリのために私を助けてください。 ありがとうございます。

+0

テーブル 'order'を呼び出さないでください - 楽しいだけではありません – Strawberry

答えて

0

私が正しく理解している場合は、注文があるかどうかに関係なく、すべての会計年度と地域を一覧にしたいと考えています。一つのアプローチは、このように、すべての会計年度を示す表を使用することです(私はMySQLを使用していないが、これはそれが標準SQLで行うの方法です):

create table fiscal_years (
    year_name text not null, 
    year_start date not null, 
    year_end date not null, 
    constraint years_pk primary key (year_start, year_end) 
); 

あなたはすべての年で、この表を移入します欲しい:受注テーブルと

insert into fiscal_years (year_name, year_start, year_end) 
values ('2007-2008', '2007-03-05', 2008-03-04'); 
-- (etc) 

あなたがすることができ、その後毎年、地域のすべての可能な組み合わせを得るために地域とのCROSS JOINこの、その後、LEFT JOINそれらを:

SELECT y.year_name, y.loc_name, 
    COALESCE(sum (o.cash), 0) as cash_total 
FROM (
    SELECT year_start, year_end, year_name, 
    location.id as loc_id, loc_name 
    FROM fiscal_years 
    CROSS JOIN location 
) y 
LEFT JOIN orders o ON (
    y.year_start < o.orderdate 
    and y.year_end >= o.orderdate 
    and o.loc_id = y.loc_id 
) 
GROUP BY y.year_name, y.loc_name 
ORDER BY y.year_name, y.loc_name; 

LEFT JOINは、右側(orders)に一致する行があるかどうかにかかわらず、結合の左側のすべての行(この場合はfiscal_yearslocation)を返します。したがって、すべての年とすべての場所リストされている。右側から一致する行がない場合は、右側のすべての列に対してNULLが返されます。したがって、COALESCE()を使用すると、代わりに0が返されます。

ところで、orderのような予約語をテーブル名として使用しないでください。構文エラーを引き起こさない場合でも、少なくとも混乱を招く可能性があります。

関連する問題