如何添加多列值?

时间:2018-06-29 06:44:34

标签: sql oracle

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;

3 个答案:

答案 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个值,那么您将需要使用COALESCENVL

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的逻辑来处理空值。