我有一个像这样结构化的数据库表(为简洁起见省略了相关字段):
rankings
------------------
(PK) indicator_id
(PK) alternative_id
(PK) analysis_id
rank
所有字段都是整数;前三个(标记为“(PK)”)是复合主键。给定的“分析”有多个“替代”,每个“替代”对于许多“指标”中的每一个都具有“等级”。
我正在寻找一种有效的方法来比较任意数量的分析,其中任何替代/指标组合的等级不同。因此,例如,如果我们有这些数据:
analysis_id | alternative_id | indicator_id | rank
----------------------------------------------------
1 | 1 | 1 | 4
1 | 1 | 2 | 6
1 | 2 | 1 | 3
1 | 2 | 2 | 9
2 | 1 | 1 | 4
2 | 1 | 2 | 7
2 | 2 | 1 | 4
2 | 2 | 2 | 9
...然后理想的方法将确定以下差异:
analysis_id | alternative_id | indicator_id | rank
----------------------------------------------------
1 | 1 | 2 | 6
2 | 1 | 2 | 7
1 | 2 | 1 | 3
2 | 2 | 1 | 4
我提出了一个查询,它可以为2个分析ID执行我想要的操作,但是我无法概括它以查找任意数量的分析ID之间的差异(即用户可能想要比较2或5,或者9,或者其他什么,找到任何至少有一个分析与其他分析不同的行)。我的疑问是:
declare @analysisId1 int, @analysisId2 int;
select @analysisId1 = 1, @analysisId2 = 2;
select
r1.indicator_id,
r1.alternative_id,
r1.[rank] as Analysis1Rank,
r2.[rank] as Analysis2Rank
from rankings r1
inner join rankings r2
on r1.indicator_id = r2.indicator_id
and r1.alternative_id = r2.alternative_id
and r2.analysis_id = @analysisId2
where
r1.analysis_id = @analysisId1
and r1.[rank] != r2.[rank]
(它将分析值放入其他字段而不是行。我认为无论哪种方式都可行。)
如何概括此查询以处理许多分析ID? (或者,或者,提出一个不同的,更好的查询来完成这项工作?)我正在使用SQL Server 2005,以防万一。
如果有必要,我总是可以从表中提取所有数据并查找代码中的差异,但是SQL解决方案会更好,因为我通常只关心几千行中的几行而且没有任何意义。如果我可以避免它,将它们全部转移。 (但是,如果你有令人信服的理由不在SQL中这样做,那么这样说 - 我也认为这也是一个很好的答案!)
答案 0 :(得分:2)
这将返回您想要的数据集 - 现在您只需要一种方法将所需的分析ID传递给查询。或者只是在您的应用程序中过滤此数据。
select r.* from rankings r
inner join
(
select alternative_id, indicator_id
from rankings
group by alternative_id, indicator_id
having count(distinct rank) > 1
) differ on r.alternative_id = differ.alternative_id
and r.indicator_id = differ.indicator_id
order by r.alternative_id, r.indicator_id, r.analysis_id, r.rank
答案 1 :(得分:1)
我不知道您使用的是哪个数据库,在SQL Server中我会这样:
-- STEP 1, create temporary table with all the alternative_id , indicator_id combinations with more than one rank:
select alternative_id , indicator_id
into #results
from rankings
group by alternative_id , indicator_id
having count (distinct rank)>1
-- STEP 2, retreive the data
select a.* from rankings a, #results b
where a.alternative_id = b.alternative_id
and a.indicator_id = b. indicator_id
order by alternative_id , indicator_id, analysis_id
顺便说一下,这里给出的其他答案需要计数(不同级别)!!!!!
答案 2 :(得分:0)
我认为这就是你要做的事情:
select
r.analysis_id,
r.alternative_id,
rm.indicator_id_max,
rm.rank_max
from rankings rm
join (
select
analysis_id,
alternative_id,
max(indicator_id) as indicator_id_max,
max(rank) as rank_max
from rankings
group by analysis_id,
alternative_id
having count(*) > 1
) as rm
on r.analysis_id = rm.analysis_id
and r.alternative_id = rm.alternative_id
答案 3 :(得分:0)
你的例子差异似乎是错误的。您说您想要分析,其中任何备选/指标组合的等级不同但示例行3和4不满足此条件。根据您的要求得出的正确结果是:
analysis_id | alternative_id | indicator_id | rank
----------------------------------------------------
1 | 1 | 2 | 6
2 | 1 | 2 | 7
1 | 2 | 1 | 3
2 | 2 | 1 | 4
您可以尝试查询:
with distinct_ranks as (
select alternative_id
, indicator_id
, rank
, count (*) as count
from rankings
group by alternative_id
, indicator_id
, rank
having count(*) = 1)
select r.analysis_id
, r.alternative_id
, r.indicator_id
, r.rank
from rankings r
join distinct_ranks d on r.alternative_id = d.alternative_id
and r.indicator_id = d.indicator_id
and r.rank = d.rank
你必须意识到,在多重分析中,你所拥有的标准是模棱两可的。如果分析1,2和3的等级1和4,5和6的替代/指标1/1的等级2怎么办?集合(1,2,3)与集合(4,5,6)“不同”,但在每个集合内部没有区别。在这种情况下你想要的行为是什么,如果他们出现了?我的查询查找所有其他分析中相同备选/指标*具有不同排名的所有记录',但不清楚这是否符合您的要求。