1

我正在尝试将查询结果插入到表中,但使用'Insert Into' xxx(col1, col2, col3...) values(....)但出现语法错误'关键字'with'附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。

知道如何在这样的复杂查询中使用“插入”吗?请注意“with Rownumbers..”查询有效并返回准确的结果,当我尝试插入该结果时只是错误。

INSERT INTO Cost(Name, [Status], [Hours]) values(
with RowNumbers (RowNum, name, [status], [DateTime])
as
(
    select
        ROW_NUMBER() over (partition by name order by [DateTime]),
        name,
        [status],
        [DateTime]
    from @T
)
select
    T1.name,
    case T1.[status]
        when 0 then 'In'
        when 1 then 'Out'
        when 2 then 'Absent'
      end as [status],
    sum(datediff(MINUTE, T1.[DateTime], T2.[DateTime]) / 60.0) as [hours]
from RowNumbers T1
    inner join RowNumbers T2
        on T1.RowNum = T2.RowNum - 1 -- joins the current row to the next one
        and T1.name = T2.name
group by T1.name, T1.[status]
order by T1.Name, T1.[status]);
4

2 回答 2

1

您的查询需要按以下方式转换:

;
with RowNumbers (RowNum, name, [status], [DateTime])
as
(
    select
        ROW_NUMBER() over (partition by name order by [DateTime]),
        name,
        [status],
        [DateTime]
    from @T
)
INSERT INTO Cost(Name, [Status], [Hours]) values(
select
    T1.name,
    case T1.[status]
        when 0 then 'In'
        when 1 then 'Out'
        when 2 then 'Absent'
      end as [status],
    sum(datediff(MINUTE, T1.[DateTime], T2.[DateTime]) / 60.0) as [hours]
from RowNumbers T1
    inner join RowNumbers T2
        on T1.RowNum = T2.RowNum - 1 -- joins the current row to the next one
        and T1.name = T2.name
group by T1.name, T1.[status]
order by T1.Name, T1.[status]);

CTE 必须在插入语句之前定义。

检查链接http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx , http://technet.microsoft.com/en-us/library/ms175972(v= sql.105).aspx以获得更深入的 CTE 理解。

于 2013-11-04T07:38:44.457 回答
1

您应该考虑将状态列设置为 smallint,而不是在存储 varchar 时浪费空间。然后制作另一个表来描述这个 varchar(规范化数据)。

我稍微重写了您的 sql,因此语法有效并且小时计算更准确:

;with RowNumbers (RowNum, name, [status], [DateTime])
as
(
    select
        ROW_NUMBER() over (partition by name order by [DateTime]),
        name,
        [status],
        [DateTime]
    from @T
)
INSERT INTO Cost(Name, [Status], [Hours])
select
    T1.name,
    case T1.[status]
        when 0 then 'In'
        when 1 then 'Out'
        when 2 then 'Absent'
      end as [status],
    datediff(MINUTE, 0, T2.[DateTime]-T1.[DateTime]) / 60.0 as [hours]
from RowNumbers T1
    inner join RowNumbers T2
        on T1.RowNum = T2.RowNum - 1 -- joins the current row to the next one
        and T1.name = T2.name
order by T1.Name, T1.[status];
于 2013-11-04T08:55:56.277 回答