假设我有一个包含3列的表:version_id
,name
,value
。
从概念上讲,此表为每个version_id
都有一堆名称 - 值对。
如何编写一个只显示前两个version_ids的名称值对的查询,其中名称值对在版本ID中不相同?
此外,我想知道是否有办法将不同的version_ids并排放置在不同的version_ids中,或者让结果在结果中彼此相邻。
基本上,我想要两个版本的差异。
示例:
version_id name value
23459 jsLibrary2 JQuery_1_4_3
23459 jsLibrary1 CrossDomainAjax_1_0
23456 jsLibrary2 JQuery_1_4_2
23456 jsLibrary1 CrossDomainAjax_1_0
23456 groovyInclude2 GroovyUtilities
23454 jsLibrary2 JQuery_1_4_2
23454 jsLibrary1 CrossDomainAjax_1_0
23454 groovyInclude2 GroovyUtilities
理想的查询结果:
23456 jsLibrary2 JQuery_1_4_2
23459 jsLibrary2 JQuery_1_4_3
23456 groovyInclude2 GroovyUtilities
23459 NULL NULL
请注意,理想情况下会注意到新的名称 - 值对(较小的version_id中不存在该名称)和已删除的名称 - 值对(其中名称在较大的version_id中不存在)
答案 0 :(得分:0)
我认为您需要使用几个子查询来获得所需的结果,因为您正在寻找第一个和第二个值。我假设你的名字是你必须分组的“关键”,在这种情况下,这些内容应该有效:
Select
firstVersion.firstVersionId,
firstVersionDetails.name as firstVersionName,
firstVersionDetails.value as firstVersionValue,
--second version values will be null if there is no second value
secondVersion.secondVersionId,
secondVersionDetails.name as secondVersionName, --always the same as firstVersionName because name is a key field
secondVersionDetails.value as secondVersionValue
From
(
Select
name,
Max(version_id) as firstVersionId
From versions
Group by name
) as firstVersion
join versions as firstVersionDetails--inner join because every name has a first version
on firstVersions.version_id = firstVersion.firstVersionId
left outer Join --outer join so we always get the first version and get the second version whenever there is one (in other words, does *not* limit data to names with at least 2 versions)
(
select
name,
Max(version_id) as secondVersionId
from versions
Group by name
) as secondVersion
on firstVersion.name=secondVersion.name
and secondVersion.version_id < firstVersion.firstVersionId --exclude the first version when calculating the 'max'. This is the part of the join that allows us to identify the second version
left outer join versions as secondVersionDetails --using outer join again so we don't limit our data to names with 2 versions
on secondVersion.secondVersionId = secondVersionDetails.version_id
快乐的查询! : - )
答案 1 :(得分:0)
这种方法怎么样 -
SELECT MAX(version_id) INTO @cur FROM tbl;
SELECT MAX(version_id) INTO @prev FROM tbl WHERE version_id < @cur;
SELECT name, @prev, MAX(IF(version_id = @prev, value, '')) AS prev_val, @cur, MAX(IF(version_id = @cur, value, '')) AS cur_val
FROM tbl
WHERE version_id IN (@prev, @cur)
GROUP BY name
HAVING cur_val <> prev_val;
答案 2 :(得分:0)
我确信这可以简化 - 或者至少,我真的希望它可以 - 但是:
SELECT name,
version_id_before,
( SELECT value
FROM property_history
WHERE name = t.name
AND version_id = version_id_before
) AS value_before,
( SELECT MIN(version_id)
FROM property_history
WHERE version_id > version_id_before
) AS version_id_after,
( SELECT value
FROM property_history
WHERE name = t.name
AND version_id =
( SELECT MIN(version_id)
FROM property_history
WHERE version_id > version_id_before
)
) AS value_after
FROM ( SELECT name,
CASE WHEN EXISTS
( SELECT 1
FROM property_history
WHERE name = ph1.name
AND version_id =
( SELECT MAX(version_id)
FROM property_history
)
)
THEN ( SELECT MAX(version_id)
FROM property_history ph2
WHERE NOT EXISTS
( SELECT 1
FROM property_history
WHERE name = ph1.name
AND version_id = ph2.version_id
AND value =
( SELECT value
FROM property_history
WHERE name = ph1.name
AND version_id =
( SELECT MAX(version_id)
FROM property_history
)
)
)
)
ELSE ( SELECT MAX(version_id)
FROM property_history
WHERE name = ph1.name
)
END AS version_id_before
FROM property_history ph1
GROUP
BY name
) AS t
WHERE version_id_before IS NOT NULL
;
(免责声明:仅使用您的示例数据集进行测试,并为其提供结果:
+----------------+-------------------+-----------------+------------------+--------------+
| name | version_id_before | value_before | version_id_after | value_after |
+----------------+-------------------+-----------------+------------------+--------------+
| groovyInclude2 | 23456 | GroovyUtilities | 23459 | NULL |
| jsLibrary2 | 23456 | JQuery_1_4_2 | 23459 | JQuery_1_4_3 |
+----------------+-------------------+-----------------+------------------+--------------+
我没有做任何努力来构建其他数据集来测试它。)