对于如下所示的访问数据库: (所有文本字段)
Co1 Co2 Co3 Co4 A k t N1 B k t N2 A m t N3 B k z N4 A k z N5 C m t N6 C k z N7 C k t N8 A k t N9 C m t N10
我需要创建一些可以执行以下操作的报告:
结果需要选择行:
1,2和3非常容易(分别由order by和Where子句)但是 #4可以在访问SQL中完成吗? 如果它不能,我将制作一个循环数据的小型C#应用程序,但我觉得这样 必须可以在SQL中做,如果可以,那肯定会好得多。
实际的查询和数据库更复杂,但#4是我被卡住的地方。
我给出的例子结果将是:
A m t N3 A k t N9 C m t N6 C m t N10 C k t N8
我相信这涵盖了所有可能的情况。
精确度,我们使用第四列(本例中的C4)来确定顺序 但它是一个带有字符和数字的文本字段。 该字段是一个字母后跟2位数字:A01,A02,.. A99,B01等... Precision#2,我不是这个数据库设计的责任人。 :P
那么,对于我们中间的SQL大师,这可以在访问SQL中完成吗?怎么样?
非常感谢您提供的任何帮助。
答案 0 :(得分:0)
如果我读了你的话:
当Co3不是t时,也不是r,那么全部 具有先前C04的其他行,其中Co1 AND Co2与当前相同 行也被排除
这相当于排除存在具有特定条件的后一行的行。你可以用NOT EXISTS子句来做到这一点:
select *
from YourTable cur
where cur.Co3 in ('t','r')
and not exists (
select *
from YourTable later
where cur.Co1 = later.Co1
and cur.Co2 = later.Co2
and later.Co3 not in ('t','r')
and CInt(Mid(later.Co4,2)) > CInt(Mid(cur.Co4,2))
)
order by cur.Co1, cur.Co2 desc, CInt(Mid(cur.Co4,2))
现在N10通常不大于N5。这就是CInt(Mid(...,2))的用途:它将N10变为10,将N5变为5。
答案 1 :(得分:0)
Andomar查询的修改,它通过使用字符代码的ASCII值来确定顺序,考虑Co4中以不同字母开头的值。我假设范围是A01 ... A99,B01 ...... B99等,B01应该被认为是“晚于”A99。
select *
from Table1 cur
where not exists (
select 1
from Table1 later
where cur.Co1 = later.Co1
and cur.Co2 = later.Co2
and later.Co3 not in ('t','r')
and (asc(left(later.Co4,1)) * 100) + CInt(Mid(later.Co4,2)) > (asc(left(cur.Co4,1)) * 100) + CInt(Mid(cur.Co4,2))
)
and cur.Co3 in ('t','r')
order by cur.Co1, cur.Co2
答案 2 :(得分:0)
还不是答案,而是回答同事的设置代码。
create table #boost (
Co1 char(1),
Co2 char(1),
Co3 char(1),
Co4 char(3)
)
insert into #boost values ('A', 'k', 't', 'N1')
insert into #boost values ('B', 'k', 't', 'N2')
insert into #boost values ('A', 'm', 't', 'N3')
insert into #boost values ('B', 'k', 'z', 'N4')
insert into #boost values ('A', 'k', 'z', 'N5')
insert into #boost values ('C', 'm', 't', 'N6')
insert into #boost values ('C', 'k', 'z', 'N7')
insert into #boost values ('C', 'k', 't', 'N8')
insert into #boost values ('A', 'k', 't', 'N9')
insert into #boost values ('C', 'm', 't', 'N10')