【发布时间】:2017-12-15 02:21:15
【问题描述】:
我有两张表,设置如下:
PMmx - 起点-终点矩阵的表格版本
Origin Destination Trips
1 1 0.2
2 1 0.3
3 1 0.4
. . .
. . .
1 1101 0.6
2 1101 0.7
3 1101 0.8
. . .
. . .
1101 1 0.2
1101 2 0.3
1101 3 0.4
ZE - 具有区域等效性的表
Precinct Zone
1 1101
2 1102
3 1111
我想在PMmx 表中选择与ZE 表中的Zone 列匹配的行条目。例如:
Origin Destination Trips
1 1101 0.6
2 1101 0.7
3 1101 0.8
. . .
. . .
1101 1 0.2
1101 2 0.3
1101 3 0.4
我还想创建一个名为Distribution 的新列,它计算Trips/(Total Trips),其中总行程将在特定区域编号上求和(通过Origin 或Destination 取决于哪一列与区域匹配等价 Zone 数字)。
例如,对于Origin 1、Destination 1101,我希望该行条目的新Distribution 值为0.6/(0.6+0.7+0.8)。
我试过下面的代码
SELECT
PMmx.Origin as Origin
,PMmx.Destination as Destination
,PMmx.Trips/sum(PMmx.Trips) as 'Distribution'
FROM PMmx
inner join ZE on Origin=ZE.Zone or Destination=ZE.Zone
Group by Origin, Destination, Trips
我不确定这是否会产生正确的结果,因为没有 group by 子句我得到 Column '2DVISUM_2031PMmx_unpiv.Origin' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 而使用 group by 子句我得到 Divide by zero error encountered.
从 inner join 开始,不应该有任何 sums 为零,所以我不确定为什么会收到此错误。
请帮忙!
编辑:我现在使用查询得到重复的行
with cte as (
select
origin, destination, trips
, SUM(Trips) over(partition by Pmx.Origin) sum_trips
, trips / SUM(Trips) over(partition by Pmx.Origin) trips_div
from Pmx
inner join ZE on Pmx.Origin = ZE.Zone
)
select
origin, destination, trips, sum_trips, trips_div
from cte
union all
select
destination, origin, trips, sum_trips, trips_div
from cte
更新表格以显示错误:
ZE:
Precinct Zone
1 1101
2 1102
3 1111
4 1211
Pmx:
Origin Destination Trips
1 1 0.20
2 1 0.30
3 1 0.40
1 1101 0.60
2 1101 0.70
3 1101 0.80
1101 1 0.20
1101 2 0.30
1101 3 0.40
1101 1211 0.60
1211 1101 0.50
输出包含具有不同行程值的重复项:
origin destination trips sum_trips trips_div
1101 1 0.20 1.50 0.13333333333333333333333333
1101 2 0.30 1.50 0.20000000000000000000000000
1101 3 0.40 1.50 0.26666666666666666666666666
1101 1211 0.60 1.50 0.40000000000000000000000000
1211 1101 0.50 0.50 1.00000000000000000000000000
1 1101 0.20 1.50 0.13333333333333333333333333
2 1101 0.30 1.50 0.20000000000000000000000000
3 1101 0.40 1.50 0.26666666666666666666666666
1211 1101 0.60 1.50 0.40000000000000000000000000
1101 1211 0.50 0.50 1.00000000000000000000000000
编辑 2: 我想创建一个“if 语句”,这样如果 Pmx.origin =ZE.Zone 则 trips_div 是 trips/SUM(Trips) over(partition by Pmx.Origin) 如上所述。但是,如果 Pmx.origin =ZE.Zone 和 Pmx.destination=ZE.Zone 那么我希望 trips_div 仍然是 trips/SUM(Trips) over(partition by Pmx.Origin)。当Pmx.origin does not equal ZE.Zone 和Pmx.destination=ZE.Zone 然后trips/SUM(Trips) over(partition by Pmx.Destination)。我尝试了各种case when 语句,但似乎无法正常工作。
我希望输出是:
origin destination trips sum_trips trips_div
1 1101 0.20 2.10 0.0952380952380952
2 1101 0.30 2.10 0.1428571428571429
3 1101 0.40 2.10 0.1904761904761905
1101 1 0.20 1.50 0.1333333333333333
1101 2 0.30 1.50 0.2000000000000000
1101 3 0.40 1.50 0.2666666666666666
1101 1211 0.60 1.50 0.4000000000000000
1211 1101 0.50 0.50 1.0000000000000000
【问题讨论】:
-
响应您的“编辑 2”请参阅 sqlfiddle.com/#!6/e8020/6 那个 case 表达式是
case when Pmx.origin <> ZE.Zone and Pmx.destination = ZE.Zone then trips/SUM(Trips) over(partition by Pmx.Destination) else trips/SUM(Trips) over(partition by Pmx.Origin) end但它对结果没有影响。
标签: sql sql-server group-by sum inner-join