在SQL Server中显示两次数据

时间:2017-08-23 09:42:36

标签: sql sql-server

我有下表:

Date   Type   Amount
Jul-17 Type A 20
Jul-17 Type B 30
Jul-17 Type C 10
Aug-17 Type A 50
Aug-17 Type D 40
Aug-17 Type C 70

我的查询只会过滤两个月,如下所示:

  

SELECT DATE,Type,Amount FROM Table 1 WHERE DATE> =' 01-Jul-2017'   和日期< =' 2017年8月31日'

我想显示7月份不存在的类型,并显示8月份不存在的金额0和类型,并显示金额0如下:

Date   Type   Amount
Jul-17 Type A 20
Aug-17 Type A 50
Jul-17 Type B 30
Aug-17 Type B 0
Jul-17 Type C 10
Aug-17 Type C 70
Jul-17 Type D 0
Aug-17 Type D 40

到目前为止,我在下面尝试过,但它影响了性能。我想在不使用union的情况下简化查询:

SELECT DATE, Type, Amount 
FROM Table 1
WHERE DATE >= '01-Jul-2017'
AND DATE <= '31-Aug-2017'

Union 

SELECT '01-Jul-2017' AS DATE, TYPE, 0 AS AMOUNT
WHERE DATE >= '01-Aug-2017'
AND DATE <= '31-Aug-2017'
AND Type NOT in (SELECT DISTINCT TYPE WHERE DATE >= '01-Jul-2017'
AND DATE <= '31-Jul-2017')

Union

SELECT '01-Aug-2017' AS DATE, TYPE, 0 AS AMOUNT
WHERE DATE >= '01-Jul-2017'
AND DATE <= '31-Jul-2017'
AND Type NOT in (SELECT DISTINCT TYPE WHERE DATE >= '01-Aug-2017'
AND DATE <= '31-Aug-2017')

3 个答案:

答案 0 :(得分:1)

您可以使用交叉联接来获取所有可能的组合,然后使用左外连接来获取实际数量...

WITH    cte
      AS ( SELECT DISTINCT
                    t1.Date ,
                    t2.Type
           FROM     dbo.Table1 t1
                    CROSS JOIN dbo.Table1 t2
           WHERE    t1.Date BETWEEN '2017-07-01' AND '2017-08-31'
                    AND t2.Date BETWEEN '2017-07-01' AND '2017-08-31'
         )
SELECT  cte.Date ,
        cte.Type ,
        COALESCE(t.Amount, 0) AS Amount
FROM    cte
        LEFT OUTER JOIN dbo.Table1 AS t ON t.Date = cte.Date
                                           AND t.Type = cte.Type;

答案 1 :(得分:0)

在开始时,我误导了你的标签,并认为你应该为MYSQL做道歉(道歉)。我最后留下了MYSQL版本。 为简洁起见,我使用了*。请用最终查询的全名列表进行更改。

这是MSSQL VERSION 您需要一次指定两个日期(在开头)。  我用TN作为表名。

   WITH TT AS (SELECT *, MONTH(DATE) AS MN from TN WHERE DATE >= '2017-07-01' AND DATE <= '2017-08-31' )
    SELECT COALESCE(C.DATE, CASE WHEN C.MN2=MINMN THEN DATEADD(MONTH,+1, C.DATE2) ELSE DATEADD(MONTH,-1, C.DATE2) END)  AS DATE
    , COALESCE(C.TYPE, C.TYPE2) AS TYPE
    , COALESCE(C.AMOUNT,0) AS AMOUNT
    FROM
    (SELECT A.*, B.DATE AS DATE2, B.TYPE AS TYPE2, B.AMOUNT AS AMOUNT2, B.MN AS MN2, X.MINMN
    from TT A
    FULL JOIN TT B ON A.MN<>B.MN AND A.TYPE = B.TYPE
     CROSS JOIN (SELECT MIN(MN) MINMN FROM TT) X
    )C
  ORDER BY DATE, TYPE     ;

输出:

    DATE               TYPE AMOUNT
1   17.07.2017 00:00:00 A   20
2   17.07.2017 00:00:00 B   30
3   17.07.2017 00:00:00 C   10
4   17.07.2017 00:00:00 D   0
5   17.08.2017 00:00:00 A   50
6   17.08.2017 00:00:00 B   0
7   17.08.2017 00:00:00 C   70
8   17.08.2017 00:00:00 D   40

MYSQL VERSION 我刚刚找到这个(它只使用一个UNION,而不是两个)。 我用TN作为表名。请检查一下表演。

SELECT * from TN WHERE DATE >= '2017-07-01' AND DATE <= '2017-08-31' 
UNION ALL
SELECT CASE WHEN MONTH(A.DATE)=M1 THEN '2017-08-01' ELSE '2017-07-01' END AS DATE, A.TYPE, 0 AS AMOUNT
from TN A
LEFT JOIN (SELECT * FROM TN WHERE DATE >= '2017-07-01' AND DATE <= '2017-08-31') B ON DATE_FORMAT(A.DATE ,'%Y-%m-01') <> DATE_FORMAT(B.DATE ,'%Y-%m-01') AND A.TYPE = B.TYPE
CROSS JOIN (SELECT MIN(MONTH(DATE)) AS M1 FROM TN WHERE DATE >= '2017-07-01' AND DATE <= '2017-08-31') X
WHERE A.DATE >= '2017-07-01' AND A.DATE <= '2017-08-31'
    AND  B.TYPE IS NULL

输出:

    Date      type  amount
1   2017-07-17  A   20
2   2017-07-17  B   30
3   2017-07-17  C   10
4   2017-08-17  A   50
5   2017-08-17  D   40
6   2017-08-17  C   70
7   2017-08-01  B   0
8   2017-07-01  D   0

答案 2 :(得分:0)

如果您想使用pivot执行结果。 您可以尝试以下查询:

select [Date] As Date_For_Table,
    [Type A] = 
    case
        when [Type A] IS NULL Then 0
        else [Type A]
    end,
    [Type B] = 
    case         
        when [Type B] IS NULL Then 0
        else [Type B]
    end,
    [Type C] = 
    case
        when [Type C] IS NULL Then 0
        else [Type C]
    end,
    [Type D] = 
    case
        when [Type D] IS NULL Then 0
        else [Type D]
    end
from 
(
select CONVERT(CHAR(4), date, 100) + CONVERT(CHAR(4), date, 120) as date ,type,Amount
from Table1
) as PivotData
pivot
(
avg(amount) for type in
([Type A],[Type B],[Type C],[Type D]))as Pivoting
order by date desc

输出: Output