我有两个查询,如下所示
查询1
set @sql = cast(N'
;with cteSales as
(
select
datepart(weekday, s.enddate) as SalesWeekDay,
datediff(hour, cast(s.enddate as date), s.enddate) DayTime,
s.enddate SalesDate,
CONVERT(DECIMAL(10,2),OrigionalSubTotal/100.0) as OrigionalSubTotal,
o.ordertype ordertype
from sale s,DinePointOrderType o
where s.enddate >= @DateBegin and s.enddate < @DateEnd
and o.ordertypeindex = s.ordertype
and s.ordertype = 1
and s.IsSuspend = 0 and s.IsTrainMode = 0
and s.IsCancelled = 0 and s.wasrefunded=0
),
cteSalesPerWeekDays as
(
select
p.hrs,
p.period,
isnull(p.ordertype,''DINE IN'') ordertype,' as nvarchar(max)) + @col_per_day_list + N'
from #Timing t
cross join #WeekDays w
left join cteSales s on datediff(hour, w.wd_date, s.SalesDate) = t.hrs
pivot
(
Sum(s.OrigionalSubTotal)
for w.wd_name in (' + @pivot_val_per_day_list + N')
) p
)
select
r.hrs,
r.period as [From-To],
r.ordertype,' + @sum_cols_per_day_list + N'
from cteSalesPerWeekDays r
group by r.hrs, r.period,r.ordertype
order by r.hrs
'
exec sp_executesql @sql, N'@DateBegin datetime, @DateEnd datetime',
@DateBegin = @DateBegin,
@DateEnd = @TradeDateEnd
GO
查询2
set @sql = cast(N'
;with cteSales as
(
select
datepart(weekday, s.enddate) as SalesWeekDay,
datediff(hour, cast(s.enddate as date), s.enddate) DayTime,
s.enddate SalesDate,
CONVERT(DECIMAL(10,2),OrigionalSubTotal/100.0) as OrigionalSubTotal,
o.ordertype ordertype
from sale s,DinePointOrderType o
where s.enddate >= @DateBegin and s.enddate < @DateEnd
and o.ordertypeindex = s.ordertype
and s.ordertype = 2
and s.IsSuspend = 0 and s.IsTrainMode = 0
and s.IsCancelled = 0 and s.wasrefunded=0
),
cteSalesPerWeekDays as
(
select
p.hrs,
p.period,
isnull(p.ordertype,''TAKE OUT'') ordertype,' as nvarchar(max)) + @col_per_day_list + N'
from #Timing t
cross join #WeekDays w
left join cteSales s on datediff(hour, w.wd_date, s.SalesDate) = t.hrs
pivot
(
Sum(s.OrigionalSubTotal)
for w.wd_name in (' + @pivot_val_per_day_list + N')
) p
)
select
r.hrs,
r.period as [From-To],
r.ordertype,' + @sum_cols_per_day_list + N'
from cteSalesPerWeekDays r
group by r.hrs, r.period,r.ordertype
order by r.hrs
'
exec sp_executesql @sql, N'@DateBegin datetime, @DateEnd datetime',
@DateBegin = @DateBegin,
@DateEnd = @TradeDateEnd
是否可以将这两个查询联合起来?
答案 0 :(得分:1)
您需要在此行上开始新的CAST:
isnull(p.ordertype,''DINE IN'') ordertype,' as nvarchar(max)) + @col_per_day_list + N'
像这样:
isnull(p.ordertype,''DINE IN'') ordertype,' as nvarchar(max)) + @col_per_day_list + CAST(N'
编辑,现在修复了该错误,你的UNION位置错误。
你不能UNION这两个CTE:
cteSalesPerWeekDays as
(...)
union
cteSales as
(...)
您只能在两个SELECT语句之间使用UNION。所以你可以制作你的CTE的Dine In和Take Out版本,然后在最终的选择中UNION它们:
SELECT ...
FROM cteSalesPerWeekDaysDINEIN
UNION
SELECT ...
FROM cteSalesPerWeekDaysTAKEOUT
答案 1 :(得分:0)
这么多代码......只需使用PIVOT和动态SQL就可以完成。
创建表以测试输出:
CREATE TABLE #Ordertypes (
ordertype_id int,
name nvarchar(10)
)
INSERT INTO #Ordertypes VALUES
(1, 'DINE IN'),
(2, 'TAKE OUT'),
(3, 'DELIVERY')
CREATE TABLE #Sale (
StartDate datetime,
Amt money,
ordertype_id int
)
INSERT INTO #Sale VALUES
('2016-06-12 10:01:15.780', 10.00, 1),
('2016-06-12 10:15:57.360', 20.00, 1),
('2016-06-12 12:48:41.250', 50.00, 2),
('2016-06-13 12:04:45.090', 15.00, 3)
CREATE TABLE #time_intervals (
tStart time,
tEnd time
)
;WITH time_intervals AS (
SELECT CAST('00:00:00' as time) as tStart,
CAST('00:59:59' as time) as tEnd
UNION ALL
SELECT DATEADD(hour,1,tStart),
DATEADD(hour,1,tEnd)
FROM time_intervals
WHERE tEnd < CAST('23:59:59' as time)
)
INSERT INTO #time_intervals
SELECT *
FROM time_intervals
主要查询:
DECLARE @dateFrom date = '2016-06-12',
@dateTo date = '2016-06-13'
DECLARE @sql nvarchar(max),
@columns nvarchar(max),
@cast_columns nvarchar(max)
SELECT @cast_columns= STUFF((
SELECT DISTINCT ',ISNULL(' + QUOTENAME(CAST(StartDate as date)) +',0.00) as ' + QUOTENAME(CAST(StartDate as date))
FROM #Sale
WHERE CAST(StartDate as date) between @dateFrom and @dateTo
FOR XML PATH('')),1,1,''),
@columns = STUFF((
SELECT DISTINCT ',' + QUOTENAME(CAST(StartDate as date))
FROM #Sale
WHERE CAST(StartDate as date) between @dateFrom and @dateTo
FOR XML PATH('')),1,1,'')
SELECT @sql = '
SELECT LEFT(tStart,5) + ''-'' + LEFT(DATEADD(second,1,tEnd),5) as Interval,
Name,
'+@cast_columns+'
FROM (
SELECT tStart,
tEnd,
ot.name,
CAST(StartDate as date) as sDate,
Amt
FROM #time_intervals t
CROSS JOIN #Ordertypes ot
LEFT JOIN #Sale s
ON CAST(s.StartDate as time) between t.tStart and t.tEnd and ot.ordertype_id = S.ordertype_id
) as p
PIVOT (
SUM(Amt) FOR sDate IN ('+@columns+')
) as pvt
ORDER BY Name, tStart'
EXEC sp_executesql @sql
输出:
Interval Name 2016-06-12 2016-06-13
00:00-01:00 DELIVERY 0.00 0.00
01:00-02:00 DELIVERY 0.00 0.00
02:00-03:00 DELIVERY 0.00 0.00
03:00-04:00 DELIVERY 0.00 0.00
04:00-05:00 DELIVERY 0.00 0.00
05:00-06:00 DELIVERY 0.00 0.00
06:00-07:00 DELIVERY 0.00 0.00
07:00-08:00 DELIVERY 0.00 0.00
08:00-09:00 DELIVERY 0.00 0.00
09:00-10:00 DELIVERY 0.00 0.00
10:00-11:00 DELIVERY 0.00 0.00
11:00-12:00 DELIVERY 0.00 0.00
12:00-13:00 DELIVERY 0.00 15.00
13:00-14:00 DELIVERY 0.00 0.00
...
09:00-10:00 DINE IN 0.00 0.00
10:00-11:00 DINE IN 30.00 0.00
11:00-12:00 DINE IN 0.00 0.00
...
11:00-12:00 TAKE OUT 0.00 0.00
12:00-13:00 TAKE OUT 50.00 0.00
13:00-14:00 TAKE OUT 0.00 0.00
14:00-15:00 TAKE OUT 0.00 0.00