给出两个表,
包含A
,customerid
,lastchange
internallink
包含B
,internallink
turnover
(我只是在这里把它改成一个通用的例子,实际的结构更复杂。现在的SQL方言是mySQL。)
唯一的独特之处(每个表)是internallink。 A中有几条记录具有相同的customerID,lastchange中的不同日期以及不同的internallink值。 还有其他与此相关的项目;我无法改变这些表格。
我需要来自A的记录ID,它是客户的最新记录(具有相同customerID的所有客户ID的最高更改值)和,B中的条目与某个值匹配条件是相互联系的。
我认为
SELECT `internallink` FROM `B` WHERE (`turnover` > 10000)
部分不是问题。
我到目前为止:
SELECT `customerID`, MAX(`lastchange`)
FROM `A`
WHERE `lastchange` IN (SELECT `internallink` FROM `B`
WHERE `turnover` > 10000)
GROUP BY `customerID`;
唉,这个陈述给出了错误的结果,因为上面会给我返回最近的值不符合标准的customerID,但是有些旧的 - 它会选择最早的那个,然后返回。但是如果最近的条目低于阈值,则customerID根本不应该出现。
我哪里出错了,对此有什么正确的解决方法?
示例数据 表A
customerid lastchange internallink 3 2010-02-11 11 3 2010-09-04 12 3 2010-10-22 13 3 2010-11-23 14 4 2010-05-05 15 4 2010-12-01 16 5 2010-11-28 17 5 2010-11-29 18
表B
internallink turnover 11 47000 12 11000 13 8000 14 15000 15 17000 16 23000 17 50000 18 10000
我的测试中的实际阈值是12000。 您可以看到customerID不应该在结果集中,因为最近的条目低于阈值。
结果集应为(3,2010-11-23)(4,2010-12-01) - 但目前它还包含(5,2010-11-28),这是错误的。
更近一点(在你的帮助下,谢谢!),这两个陈述都有效:
SELECT customerID,MAX(lastchange),internallink FROM A GROUP BY customerID; SELECT internallink FROM B WHERE(营业额> 12000);
现在我所需要的只是两者的交集......用正确的逻辑!
答案 0 :(得分:1)
以下查询应该执行您想要的操作。 不是编写此类查询的最佳方式。但它使用的是标准SQL,并且可以在任何数据库中执行。
这样的工作:内部子查询找到所有customerid以及最新的更改。对于每个这样的对(customerid,lastchange),我们在表A中找到原始行。在表A中找到一行后,我们使用internallink在B中查找匹配的记录,但仅当相关的营业额大于10000时。
drop table a;
drop table b;
create table a(
customerid int not null
,lastchange date not null
,internallink int not null
);
create table b(
internallink int not null
,turnover int not null
);
insert into a values(3, date '2010-02-11', 11);
insert into a values(3, date '2010-09-04', 12);
insert into a values(3, date '2010-10-22', 13);
insert into a values(3, date '2010-11-23', 14);
insert into a values(4, date '2010-05-05', 15);
insert into a values(4, date '2010-12-01', 16);
insert into a values(5, date '2010-11-28', 17);
insert into a values(5, date '2010-11-29', 18);
insert into b values(11, 47000);
insert into b values(12, 11000);
insert into b values(13, 8000);
insert into b values(14, 15000);
insert into b values(15, 17000);
insert into b values(16, 23000);
insert into b values(17, 50000);
insert into b values(18, 10000);
select a.customerid
,a.lastchange
,a.internallink
,b.turnover
from a
join b on (a.internallink = b.internallink)
where b.turnover > 10000
and (a.customerid, a.lastchange) in(select customerid,max(lastchange)
from a
group by customerid);
答案 1 :(得分:0)
这适用于sql server - 我不确定mySql是否有类似的排名功能。
select a.id, a.lastchange, b.turnover, a.rownumber from B b inner join
(SELECT id, lastchange, internallink, ROW_NUMBER() OVER(PARTITION BY id ORDER BY lastchange DESC) AS 'rownumber'
FROM A) a on b.internallink = a.internallink
where a.rownumber = 1 and b.turnover > 5000
“ROW_NUMBER()OVER(PARTITION BY id ORDER BY lastchange DESC)AS'rownumber'”表示......
我想将所有相同的ID组合在一起,并在每行计数之后通过desc的lastchange命令它们。哦,并列出列rownumber。
id lastchange internallink rownumber
1 2010-01-03 2 1
1 2010-01-02 1 2
1 2010-01-01 1 3
2 2010-01-04 2 1
选择rownumber为1的任何记录将返回id的最后修改记录。
答案 2 :(得分:0)
经过大量的测试和一些研究后,我找到了这个解决方案,并发布了 如果其他人应该遇到类似的问题。
附加表“cache”保留表A中最新条目的副本,大大降低了复杂性。它通过使用这样的触发器保持最新:
CREATE TRIGGER sync_a_insert AFTER INSERT ON a FOR EACH ROW INSERT INTO cache (`customerID`, `internallink`) VALUES (NEW.`customerID`,NEW.`internallink`); CREATE TRIGGER sync_a_update AFTER UPDATE ON a FOR EACH ROW UPDATE cache SET `internallink` = NEW.`internallink` WHERE (`customerID` = NEW.`customerID`); CREATE TRIGGER sync_a_delete BEFORE DELETE ON a FOR EACH ROW DELETE FROM cache WHERE `customerID` = OLD.`customerID`;
对于INSERT和UPDATE,这些触发器在事后发生,因此表a中的条目在缓存更新之前完成。对于DELETE,需要在原始条目消失之前更新缓存。
一旦到位,其他一切都变得简单:
SELECT `customerID` FROM cache WHERE `internallink` IN (SELECT `internallink` FROM b WHERE (`turnover` > 10000));
对我来说,这是一个可行的解决方案,它甚至可以加快查找速度。当然,数据库大小有成本,但我认为整体性能要好得多 - 只要至少有一个读访问权限比写访问权限更多,就会有所改进。
但是,你给出的答案对我很有帮助。我从他们那里学到了很多东西,并试图遵循你的建议(甚至把它的一部分用于其他地方)。感谢所有回答我问题的人!