SQL查询帮助:可能涉及分组依据
我的软件运行在几个数据库上,所以我需要通用(注意,我认为“独特的”解决方案可能会起作用,但这不是标准的) 假设我有两个表,定义为:SQL查询帮助:可能涉及分组依据,sql,join,group-by,Sql,Join,Group By,我的软件运行在几个数据库上,所以我需要通用(注意,我认为“独特的”解决方案可能会起作用,但这不是标准的) 假设我有两个表,定义为: Table A: id, time (pk: id) Table B: id(fk), key, value (pk: id, key) 其中,表B的id是表a的外键,主键是指定的 我需要请求的密钥的最新(及时)值。假设我有如下数据: id | key | value 1 | A | v1 1 | B | v2 1 | C | v3 2 | A
Table A: id, time (pk: id)
Table B: id(fk), key, value (pk: id, key)
其中,表B的id是表a的外键,主键是指定的
我需要请求的密钥的最新(及时)值。假设我有如下数据:
id | key | value
1 | A | v1
1 | B | v2
1 | C | v3
2 | A | v4
2 | C | v5
3 | B | v6
3 | D | v7
如果id的时间在增加,并且我想要键A和键C的值,我希望得到如下结果:
key | value
A | v4
C | v5
或对于键D和A:
key | value
D | v7
A | v4
理想情况下,对于n个键请求,我只会返回n行。单次查询是否可以执行类似操作?以下是使用SQL Server 2008 R2时可能遇到的问题: 模式
CREATE TABLE B (
ind integer,
[key] varchar(8),
value varchar(16)
);
INSERT INTO B VALUES (1, 'A', 'v1');
INSERT INTO B VALUES (1, 'B', 'v2');
INSERT INTO B VALUES (1, 'C', 'v3');
INSERT INTO B VALUES (2, 'A', 'v4');
INSERT INTO B VALUES (2, 'C', 'v5');
INSERT INTO B VALUES (3, 'B', 'v6');
INSERT INTO B VALUES (3, 'D', 'v7');
INSERT INTO B VALUES (3, 'A', 'v12');
INSERT INTO B VALUES (3, 'C', 'v17');
INSERT INTO B VALUES (3, 'C', 'v101');
查询
select [key], max(CAST(SUBSTRING(value, 2, LEN(value)) as INT)) from B
where [key] in ('A', 'C')
group by [key]
如果要保留v作为前缀,请执行以下操作:
select [key], 'v' + CAST(max(CAST(SUBSTRING(value, 2, LEN(value)) as INT)) as VARCHAR) as Value
from B
where [key] in ('A', 'C')
group by [key]
输出
| KEY | VALUE |
------------------
| A | v12 |
| C | v101 |
要使用的SQL小提琴:我假设没有ID值具有相同的时间值 我相信,通过选择在尽可能多的数据库上运行,您可以获得以下内容。但是,平台灵活性的折衷不如最佳性能 别名为t的子查询标识每个键的最新可用时间
select a.id,
a.time,
b.key,
b.value
from tableB as b
inner join tableA as a
on a.id=b.id
inner join (
select b2.key,
max(a2.time) time
from tableB as b2
inner join tableA as a2 on a2.id=b2.id
group by b2.key
) as t on a.time = t.time and b.key = t.key
where b.key in ('D','A')
WHERE子句可以在子查询中移动,并且在具有原语优化器的数据库上的性能可能会稍好一些。但是将WHERE子句放在外部查询中可以更容易地维护,并且还可以在不使用WHERE子句的情况下创建视图。然后可以将WHERE子句添加到视图中的select
使用ROW_NUMBER()的查询效率更高,或者使用类似Oracle的KEEP LAST的查询更好。但是这些特性会使查询对某些平台的限制更大。为什么不将
值
存储为整数而不是字符串?这将使事情变得更简单、更快。您想要最大A.时间还是最大B.值?value
是字符串吗?一个整数?@João-我解释这个问题是问与max A.time.Mark相对应的B.value:这个值实际上是float,这个例子只是为了说明。Joao:看看dbenham说了什么,这就是我要找的。查询只是得到某种形式的max(value),而不是我如何解释这个问题。我的理解是OP希望确定每个键的最近可用时间{max(time)},然后报告与该时间相关的值。谢谢你的帮助,但是我要到星期一才能测试。我会给你回复结果的。德本汉是对的,这根本不是我想要的,很抱歉让你困惑,但是谢谢你的帮助。谢谢你的帮助,但是我要到星期一才能测试。到时候我会给你回复结果的。哇,那太令人印象深刻了。。。我很肯定你已经明白了。我唯一需要做的更改是在最后,我的db不喜欢b2.key in(…),我不得不将其更改为b.key。我还需要确认,但我很确定你已经知道了。。。干得好!谢谢@谢谢。你是对的,我的WHERE子句使用了错误的别名。我已经修好了。