使用 union 组合多个计算

问题描述 投票:0回答:2

我有多个使用联合的计算,我正在尝试将它们组合起来,以便我可以将它们加载到同一行的新表中。

下面是一个计算示例,我总共有8个。我想通过存储过程将结果加载到新的汇总表中,但我不确定如何继续组合/加载这些计算。

汇总表将包含 8 个计算列、名称列和加载日期。它只会包含 1 行,因为数据会在一天中删除并重新加载。

--current day

select Name, count(cast (id as int))  as current_day from (
    select Name,id from [Table1]
    where CONVERT(DATE, dte_Uploaded) = CONVERT(DATE, CURRENT_TIMESTAMP)
    union all
    select Name,id from from [Table2]
    where CONVERT(DATE, dte_Uploaded) = CONVERT(DATE, CURRENT_TIMESTAMP)

) x group by Name



--current week


select Name, count(cast (id as int))  as current week from (
    select Name,id from [Table1]
    where DATEDIFF(ww, dte_Uploaded, GETDATE()) = 0
    union all
    select Name,id from from [Table2]
    where DATEDIFF(ww, dte_Uploaded, GETDATE()) = 0


) x group by  Name


--current month


select Name, count(cast (id as int))   as current_month from (
    select Name,id from [Table1]
    where DATEDIFF(m, dte_Uploaded, GETDATE()) = 0
    union all
    select Name,id from from [Table2]
    where DATEDIFF(m, dte_Uploaded, GETDATE()) = 0


) x group by  Name
sql sql-server stored-procedures union
2个回答
0
投票

如果目标表仅包含一行,我认为您发布的每个查询也仅包含一行。因为,如果他们不这样做,你怎么知道该选择哪一行?

无论如何:一种选择是使用您当前的查询作为 CTE(公共表表达式;使用子查询的方式),交叉连接它们并获取您感兴趣的列。

例如:

with 
current_day as(
select Name, count(cast (id as int))  as current_day from (
    select Name,id from [Table1]
    where CONVERT(DATE, dte_Uploaded) = CONVERT(DATE, CURRENT_TIMESTAMP)
    union all
    select Name,id from from [Table2]
    where CONVERT(DATE, dte_Uploaded) = CONVERT(DATE, CURRENT_TIMESTAMP)
) x group by Name),
current_week as(

select Name, count(cast (id as int))  as current_week from (
    select Name,id from [Table1]
    where DATEDIFF(ww, dte_Uploaded, GETDATE()) = 0
    union all
    select Name,id from from [Table2]
    where DATEDIFF(ww, dte_Uploaded, GETDATE()) = 0
) x group by  Name),
current month as
(
select Name, count(cast (id as int))   as current_month from (
    select Name,id from [Table1]
    where DATEDIFF(m, dte_Uploaded, GETDATE()) = 0
    union all
    select Name,id from from [Table2]
    where DATEDIFF(m, dte_Uploaded, GETDATE()) = 0
) x group by  Name)
select a.name, a.current_day, b.current_week, c.current_month
from current_day a cross join current_week b cross join current_month c;

如果交叉连接不起作用,那么您应该知道如何正确连接每个 CTE 返回的结果。


最后,如何向目标表中插入值呢?像这样:

insert into target (name, current_day, current_week, current_month)
with current_day as (the whole query posted above goes here)
select a.name, a.current_day, b.current_week, c.current_month
from current_day a cross join current_week b cross join current_month c

0
投票

如果您提前计算适当的日期范围并使用 条件聚合 来计算计数,您可能会获得更好的性能和更高的可读性。

计算日期范围时,通常会计算“包含”开始日期和“排除”结束日期(当天开始时的 00:00:00)。这可以很好地处理日期/时间字段,而无需截断潜在的索引列值。 条件聚合将聚合函数(在本例中为

COUNT()

)与CASE表达式相结合,包括或排除聚合中的每个值。对于

COUNT()
,会计算
THEN 1
行,而不会计算隐式
ELSE NULL
行。
尝试类似:
-- Day, week, and month ranges. (End dates are exclusive.)
DECLARE @now DATETIME = GETDATE()
DECLARE @day_start = DATETRUNC(day, @now)
DECLARE @day_end = DATEADD(day, 1, @day_start)
DECLARE @week_start = DATETRUNC(week, @now)
DECLARE @week_end = DATEADD(week, 1, @week_start)
DECLARE @month_start = DATETRUNC(month, @now)
DECLARE @month_end = DATEADD(month, 1, @month_start)

-- Overall range (to limit initial data retrieval)
DECLARE @range_start = LEAST(@week_start, @month_start)
DECLARE @range_end = GREATEST(@week_end, @month_end)

SELECT
    Name,
    COUNT(CASE WHEN dt >= @day_start AND dt < @day_end THEN 1 END) AS current_day,
    COUNT(CASE WHEN dt >= @week_start AND dt < @week_end THEN 1 END) AS current_week,
    COUNT(CASE WHEN dt >= @month_start AND dt < @month_end THEN 1 END) AS current_month
FROM (
    SELECT Name, dte_Uploaded AS dt
    FROM Table1
    WHERE dte_Uploaded >= @range_start AND dte_Uploaded < @range_end
    UNION ALL
    SELECT Name, dte_Uploaded AS dt
    FROM Table2
    WHERE dte_Uploaded >= @range_start AND dte_Uploaded < @range_end
) X
GROUP BY Name

© www.soinside.com 2019 - 2024. All rights reserved.