Picture is of table in the database
我必须查询在2010年1月至2012年12月之间行驶了超过430,000英里的驾驶员。 我要为此而努力
SELECT t.DRIVERID
FROM BBI_BC.TRUCKS t
WHERE t.JAN_2010_MILES + t. FEB_2010_MILES + .....+ t.DEC_2012_MILES > 43000;
答案 0 :(得分:4)
所以问题是,如何避免在WHERE子句中键入所有这些列。答案是你做不到。该表的设计者选择忽略已建立的行业标准数据库规范化规则。 Find out more.为什么这样做无关紧要:结果是,查询表的每个人都必须编写乏味且难以维护的查询。
有动态查询生成的选项:运行此查询,然后将输出剪切'n'粘贴到WHERE子句中:
select ' + t.' || column_name
from all_tab_columns
where owner = 'BBI_BC'
and table_name = 'TRUCKS'
and (column_name like '%2010_MILES'
or column_name like '%2011_MILES'
or column_name like '%2012_MILES')
order by column_id;
我怀疑这是一个作业问题。重要的是,您必须意识到真正的教训是:数据建模非常重要,而反规范化是Teh Suck!
即使表列的命名方式也很糟糕:将其命名为MILES_2010_01,MILES_2010_02等会更好,因为至少您可以将动态查询编写为
where column_name between 'MILES_2010_01' and 'MILES_2012_12'
使用正确建模的表-即每个月都有记录,而MONTHLY_MILES和MONTHLY_GAS只有两列-查询将如下所示:
SELECT t.DRIVERID
FROM BBI_BC.TRUCKS t
WHERE t.year between 2010 and 2012
group by t.driverid having sum(t.monthly_miles) >43000
答案 1 :(得分:2)
如果值可以包含NULL
个值,那么您将需要使用COALESCE
或NVL
:
SELECT DRIVERID
FROM BBI_BC.TRUCKS
WHERE COALESCE( JAN_2010_MILES, 0)
+ COALESCE( FEB_2010_MILES, 0)
+ .....
+ COALESCE( DEC_2012_MILES, 0) > 430000;
如果要自动生成查询,则:
SELECT 'SELECT DRIVERID
FROM BBI_BC.TRUCKS
WHERE ' || LISTAGG( 'COALESCE( ' || TO_CHAR( ADD_MONTHS( DATE '2010-01-01', LEVEL - 1 ), 'MON_YYYY' ) || '_MILES, 0)', '
+ ' ) WITHIN GROUP ( ORDER BY LEVEL ) || ' > 430000;' AS sql
FROM DUAL
CONNECT BY ADD_MONTHS( DATE '2010-01-01', LEVEL - 1 ) <= DATE '2012-12-01';
哪个输出:
SELECT DRIVERID
FROM BBI_BC.TRUCKS
WHERE COALESCE( JAN_2010_MILES, 0)
+ COALESCE( FEB_2010_MILES, 0)
+ COALESCE( MAR_2010_MILES, 0)
+ COALESCE( APR_2010_MILES, 0)
+ COALESCE( MAY_2010_MILES, 0)
+ COALESCE( JUN_2010_MILES, 0)
+ COALESCE( JUL_2010_MILES, 0)
+ COALESCE( AUG_2010_MILES, 0)
+ COALESCE( SEP_2010_MILES, 0)
+ COALESCE( OCT_2010_MILES, 0)
+ COALESCE( NOV_2010_MILES, 0)
+ COALESCE( DEC_2010_MILES, 0)
+ COALESCE( JAN_2011_MILES, 0)
+ COALESCE( FEB_2011_MILES, 0)
+ COALESCE( MAR_2011_MILES, 0)
+ COALESCE( APR_2011_MILES, 0)
+ COALESCE( MAY_2011_MILES, 0)
+ COALESCE( JUN_2011_MILES, 0)
+ COALESCE( JUL_2011_MILES, 0)
+ COALESCE( AUG_2011_MILES, 0)
+ COALESCE( SEP_2011_MILES, 0)
+ COALESCE( OCT_2011_MILES, 0)
+ COALESCE( NOV_2011_MILES, 0)
+ COALESCE( DEC_2011_MILES, 0)
+ COALESCE( JAN_2012_MILES, 0)
+ COALESCE( FEB_2012_MILES, 0)
+ COALESCE( MAR_2012_MILES, 0)
+ COALESCE( APR_2012_MILES, 0)
+ COALESCE( MAY_2012_MILES, 0)
+ COALESCE( JUN_2012_MILES, 0)
+ COALESCE( JUL_2012_MILES, 0)
+ COALESCE( AUG_2012_MILES, 0)
+ COALESCE( SEP_2012_MILES, 0)
+ COALESCE( OCT_2012_MILES, 0)
+ COALESCE( NOV_2012_MILES, 0)
+ COALESCE( DEC_2012_MILES, 0) > 430000;
答案 2 :(得分:2)
这与APC的解决方案类似,但会动态返回结果。 (适用于12c +)
{{1}}
当然,您可以添加类似MT0的逻辑来处理空值。