Frage

I am trying to insert the results of a query into a table using 'Insert Into' xxx(col1, col2, col3...) values(....) but getting syntax error 'Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.'

Any idea how to use 'insert' with a complex query like this? Note the 'with Rownumbers..' query works and returns an accurate result, just errors when i try to insert that result.

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]);
War es hilfreich?

Lösung

You should consider having the status column as smallint instead of wasting space on storing a varchar. Then make another table to describe this varchar (normalizing data).

I rewrote your sql a bit so the syntax is valid and the hour calculation is more accurate:

;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];

Andere Tipps

your query need to be converted in the following manner:

;
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 must be the defined before the insert statement.

Check the links http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx, http://technet.microsoft.com/en-us/library/ms175972(v=sql.105).aspx for more deep CTE understanding.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top