我正在使用零件/摩托车配件Mysql数据库,其中所有零件都链接到可以安装的所有摩托车。它看起来像这样:
part_number motorcycle year
1000 HONDA_CBR1000 2008
1000 HONDA_CBR1000 2009
1000 HONDA_CBR1000 2010
1000 HONDA_CBR1000 2011
1000 HONDA_CBR1000 2012
1000 HONDA_CBR1000 2013
1001 HONDA_CBR600 2008
1001 HONDA_CBR600 2009
1001 HONDA_CBR1000 2008
1001 HONDA_CBR1000 2009
1001 HONDA_CBR1000 2013
所以这意味着:
不幸的是,表(大约有650,000行)并不总是正确填充。在此示例中,您将注意到以下行缺失:
part_number motorcycle year
1001 HONDA_CBR1000 2010
1001 HONDA_CBR1000 2011
1001 HONDA_CBR1000 2012
因为可以在2008年,2009年和2013年安装在HONDA_CBR1000上的部件#1001也可以在(2010年,2011年和2012年)之间的“被遗忘”年份安装。
所以简单的查询:
SELECT * FROM mytable WHERE motorcycle = 'HONDA_CBR1000' AND year = '2011'
只能检索部件#1000的行(实际上,部件#1001也可以安装在这辆自行车上)。
用简单的英语,我想像
这样的查询SELECT * FROM mytable WHERE motorcycle = 'HONDA_CBR1000'
AND ("minimum year of part_number applicable to HONDA_CBR1000" <= '2011')
AND ("maximum year of part_number applicable to HONDA_CBR1000" >= '2011')
将检索所有结果(1000和1001)。
但是我怎么能在SQL中问这个?你认为它会太慢吗?
感谢您的帮助!
答案 0 :(得分:1)
SELECT part_number, max(year), Min(year)
FROM mytable
WHERE motorcycle = 'HONDA_CBR1000'
Group By part_number
Having Min(year) <= 2011
And max(year) >= 2011
*********************编辑****************
为了提高性能,请试试这个, 1)
SELECT part_number
FROM mytable t,
(Select part_number, Min(year) Minyear, max(year) Maxyear
FROM mytable
Group BY part_number) t1
WHERE t.motorcycle = 'HONDA_CBR1000'
AND t.year Between MinYear and Maxyear
AND t.year = '2011'
*********************编辑2 ************************ **********
所以这是将列出错过的年份的查询。您可以将整个查询放入插入语句
SELECT partsnumber , yrs.allyears
FROM (Select max(year) maxyear, min(year) minyear, partsnumber
FROM yourtable
group by partsnumber) q1
(Select 1950+1+b+a*10 as allyears
from (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) a,
(select 0 as b union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) b) y
Where yrs.allyears between maxyear and minyear
MINUS
SELECT partsnumber , yrs.allyears
From yourtable
yrs - &gt;从1950年到2050年产生多年的子查询(如果你有更多的年份(超过2050年或1950年之前),那么这必须改变)
选择每个产品编号的最小和最大年份之间的年份。然后用yrs table作为参考,找到最小和最大年份之间的年份。
上述查询的结果将给出min和max之间的所有年份。减号将给出错过的年份
答案 1 :(得分:0)
这是我获得零件和摩托车的所有组合以及没有数据的年份的方法。
生成所有年份的所有行,然后过滤掉您拥有的行。第一部分使用cross join
。第二个left join
:
select pm.part_number, pm.motorcycle, y.year
from (select part_number, motorcycle, min(year) as miny, max(year) as maxy
from mytable
group by part_number, motorcycle
) pm cross join
(select distinct year
from mytable
) y
on y.year between pm.miny and pm.maxy left join
mytable t
on t.part_number = pm.part_number and t.motorcycle = pm.motorcycle and
t.year = y.year
where y.year is null;
这假设所有年份都在你的桌子上,某处。 y
表只是一个年份列表,因此您可以从另一个表或通过创建派生表获取它。子查询只是获取它的一种方便方法。