将表格的两(2)列相乘

时间:2018-06-23 14:07:52

标签: sql sql-server tsql

在特定日期,我需要将作业类型总数与MEAL_Ticket的值相乘

SELECT DISTINCT 
    DATENAME(dw, Time) + ', ' + CONVERT(VARCHAR(12), Time, 107) AS Date_to_Display,Vale,
    (SELECT COUNT(*) FROM CanLog AS c 
     WHERE c.Time= clog.Time AND jobtype = 'fulltime') AS Fulltime,
    (SELECT COUNT(Jobtype) * SUM(Value) FROM CanLog 
     WHERE Time BETWEEN '2018-02-12' AND '2018-02-14' AND jobtype = 'fulltime' ) AS FulltimeTicket_Value,
    (SELECT COUNT(*) FROM CanLog AS c 
     WHERE c.Time = clog.Time AND jobtype = 'contract') AS Contract,
    (SELECT COUNT(*) FROM CanLog AS c 
     WHERE c.Time = clog.Time AND jobtype = 'casual') AS Casual
FROM 
    CanLog AS clog
WHERE 
    Time BETWEEN '2018-02-12' AND '2018-02-14' 
GROUP BY 
    Time, Jobtype 
ORDER BY 
    2 ASC

我收到此错误

  

选择列表中的'CanLog.Value'列无效,因为它不包含在聚合函数或GROUP BY子句中

我想要的是此输出:

           Fulltime   FulltimeTicket_Value     Contract       Casual
2018/06/04         1       500(1*500)                  6            2
2018/06/05         3      1500(3*500)                  0            0
2018/06/06         0       0  (0*500)                  3            1
2018/06/07         2      1000(2*500)                  1            0
2018/06/08         1       500(1*500)                  1            3
2018/06/09         0         0(0*500)                  1            4

请帮助

编辑:

样品表

CREATE TABLE [dbo].[CanLog]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Firstname] [nvarchar](50) NOT NULL,
    [Designation] [nvarchar](50) NOT NULL,
    [Jobtype] [nvarchar](50) NOT NULL,
    [Employ_No] [nvarchar](50) NOT NULL,
    [Receipt_No] [int] NOT NULL,
    [Username] [nvarchar](50) NOT NULL,
    [Time] [datetime] NOT NULL, 
    [Value] [int] NULL
) ON [PRIMARY]

2 个答案:

答案 0 :(得分:2)

初始查询有很多警告信号:

  • GROUP BY与SELECT不匹配
  • DISTINCT + GROUP BY
  • 不必要的子查询可以替换为条件聚合
  • 位置订单依据
  • 我建议避免使用列名,例如“值/时间”
  • Datename(dw, Time) + ', ' + CONVERT(VARCHAR(12), Time, 107)我将其替换为CAST(Time AS DATE)
  • Time BETWEEN '2018-02-12' AND '2018-02-14'这种比较可能很危险(如@Gordon所述)

我相信您想要类似的东西

SELECT 
    Date_to_Display = CAST(Time AS DATE),
    Fulltime = SUM(CASE WHEN jobtype = 'fulltime' THEN 1  ELSE 0 END),
    FulltimeTicket_Value = SUM(CASE WHEN jobtype = 'fulltime' THEN 1 ELSE 0 END) *
                               MAX(CASE WHEN jobtype = 'fulltime' THEN Value ELSE 0 END),
    Contract = SUM(CASE WHEN jobtype = 'contract' THEN 1 ELSE 0 END),
    Casual = SUM(CASE WHEN jobtype = 'casual' THEN 1 ELSE 0 END) 
FROM 
    CanLog AS clog
WHERE 
    Time >= '2018-02-12' and time < '2018-02-15' 
GROUP BY 
    CAST(Time AS DATE)
ORDER BY 
    CAST(Time AS DATE);

答案 1 :(得分:1)

除了Lukasz提出的许多要点外,您还应避免在日期/时间列上使用between。 Aaron Bertrand的博客What do Between and the Devil Have In Common中有一个很好的解释。

您还可以使用指标变量简化逻辑:

select cast(time as date) as Date_to_Display,
       sum(is_fulltime) as Fulltime,
       sum(value * is_fulltime) as FulltimeTicket_Value,
       sum(is_contract) as Contract,
       sum(is_casual) as Casual
from CanLog cl cross apply
     (values (case when cl.jobtype = 'fulltime' then 1 else 0 end),
             (case when cl.jobtype = 'contract' then 1 else 0 end),
             (case when cl.jobtype = 'casual' then 1 else 0 end)
     ) v(is_contract, iscasual)
where Time >= '2018-02-12' and time < '2018-02-15' 
group by cast(time as date) 
order by cast(time as date);