我有以下格式的資料,我正在嘗試使用 SQL 進行比較:
資料是“組”的評級,每組最多有 4 個值:
tbl評分
| 評級ID | 組ID | 價值1 | 價值2 | 價值3 | 價值4 |
|---|---|---|---|---|---|
| 1 | 2222 | 13 | 19 | (空值) | (空值) |
| 2 | 2222 | 13 | (空值) | (空值) | (空值) |
| 3 | 2223 | 1 | (空值) | (空值) | (空值) |
| 4 | 2223 | 1 | (空值) | (空值) | (空值) |
| 5 | 2224 | 5 | (空值) | (空值) | (空值) |
| 6 | 2225 | 10 | 12 | 13 | (空值) |
| 7 | 2225 | 12 | 13 | 10 | (空值) |
我的目標是比較記錄并確定哪些 GroupID 有兩個匹配的評級,匹配定義為任何順序的相同值串列,所有空值都被忽略。因此,在示例資料中,GroupID 2223 和 2225 有匹配,而其他沒有。
您將如何進行這種比較?
作為第一步,我使用聯合查詢將資料標準化為每行一個值,如下所示:
qryRatingsNormalized
| 評級ID | 組ID | 價值 |
|---|---|---|
| 1 | 2222 | 13 |
| 1 | 2222 | 19 |
| 2 | 2222 | 13 |
| 3 | 2223 | 1 |
| 4 | 2223 | 1 |
| 5 | 2224 | 5 |
| 6 | 2225 | 10 |
| 6 | 2225 | 12 |
| 6 | 2225 | 13 |
| 7 | 2225 | 12 |
| 7 | 2225 | 13 |
| 7 | 2225 | 10 |
但是我不確定如何從那里開始。
僅供參考,我正在使用 SQL Server 中鏈接的表在 MS Access 中作業。
uj5u.com熱心網友回復:
我并沒有真正跟上 Access/Jet SQL 的狀態,但我相當肯定這是一個有效的查詢。我的建議是,您可以通過匹配一組聚合值來逃避匹配,這些聚合值代表匹配單個值。
select r1.RatingID, r2.RatingID, r1.GroupID
from
(
select
GroupID, RatingID,
count(Value) cnt, sum(Value) tot,
avg(Value) avg, min(Value) as lst, max(Value) as grt,
/* assumes no zeroes */
floor(sum(log(Value 10)) * 100000) as lg
from qryRatingsNormalized
group by GroupID, RatingID
) r1
inner join
(
select
GroupID, RatingID,
count(Value) cnt, sum(Value) tot,
avg(Value) avg, min(Value) as lst, max(Value) as grt,
floor(sum(log(Value 10)) * 100000) as lg
from qryRatingsNormalized
group by GroupID, RatingID
) r2 on r2.GroupID = r1.GroupID and r2.RatingID > r1.RatingID
and r2.cnt = r1.cnt and r2.lst = r1.lst and r2.grt = r1.grt
and r2.tot = r1.tot and r2.avg = r1.avg and r2.lg = r1.lg
我已經重復了兩次相同的子查詢,所以可能只想將其定義為命名查詢/視圖,并使其在沒有命名子查詢的情況下作業。
您的最大值為四個值可能是有利的。這個想法是,通過比較總數、乘積(通過對數)、平均值、計數、最小值和最大值,您將極有可能認為這些集合必須是相同的。這很像校驗和。
其中一些可能取決于您是否需要重復執行此操作,或者只是一次性執行此操作,實際值是多少,您有多少總評級/組,負數是否有效......
https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=1b7b05c44d6935d43e54b012ebc0b486
uj5u.com熱心網友回復:
您可以嘗試使用 tsql 設定傳遞查詢以繞過訪問限制:
with r as (
select GroupID, RatingID, val,
row_number() over (partition by RatingID order by val) as rn,
count(*) over (partition by RatingID) as cnt
from tblRatings cross apply
(values (Value1), (Value2), (Value3), (Value4)) as v (val)
where val is not null
)
select r1.RatingID, r2.RatingID, min(r1.GroupID) as GroupID
from r r1 left outer join r r2 on
r2.GroupID = r1.GroupID and r2.RatingID > r1.RatingID
and r2.cnt = r1.cnt
and r2.rn = r1.rn and r2.val = r1.val
group by r1.RatingID, r2.RatingID
having count(r2.val) = count(*) and count(*) = min(r2.cnt);
請參閱此處的作業示例:
https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=1b7b05c44d6935d43e54b012ebc0b486
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/466146.html
下一篇:創建函式以根據輸入引數回傳行集
