有没有办法将几个不同的查询(几乎相同)压缩成一个?

时间:2009-09-14 10:02:50

标签: mysql

我有大约4或5个不同的查询,这些查询都与WHERE子句中包含的内容完全相同。例如,这些报表按日期运行,因此一个报表使用Now()日期,其他报表按月和15天使用日期。所有字段都完全相同。有没有办法将这些组合成一个查询,只是动态更改WHERE子句中的数据?或者其他一些解决方案??

由于


好的伙计们,谢谢你的回复。这是实际的查询。请注意where子句是唯一不同的东西,我真的很讨厌在我需要添加新报告时编写几乎完全相同的查询。

SELECT t1.customer_id, t1.name, t2.dtime, t6.band_type, t7.dop, t5.lun, t2.rpt
FROM
customer AS t1
Inner Join report AS t2 ON t1.customer_id = t2.customer_id
Inner Join employee AS t5 ON t5.employee_id = t2.employee_id
Inner Join band_type AS t6 ON t6.band_type_id = t2.band_type_id
Inner Join dop AS t7 ON t7.dop_id = t2.dop_id
WHERE
t2.rpt_type = 'daily' AND
t2.tmstamp >= date_sub(curdate(), interval 1 month) AND
t2.tmstamp <= curdate() AND
t1.customer_id = ''



WHERE
t2.tmstamp >= '$date 00:00:00' AND
t2.tmstamp <= '$date 23:59:59' AND
t1.customer_id = '' AND
t2.deleted =  '0'


WHERE
t2.stamp >= date_sub(now(), interval 1 day) AND
t1.customer_id = '' AND
t2.band_type = '' AND
t2.deleted = '0'

3 个答案:

答案 0 :(得分:0)

使用ORUNION ALL

SELECT  *
FROM    mytable
WHERE   date = NOW() OR date = NOW() - INTERVAL 1 DAY

SELECT  *
FROM    mytable
WHERE   date = NOW()
UNION ALL
SELECT  *
FROM    mytable
WHERE   date = NOW() - INTERVAL 1 DAY

<强>更新

如果您需要三个结果集,则需要三个查询,如果您有三个查询,则会有三个SELECT列表。

您可以在应用程序中撰写查询(创建SELECT列表一次,只需添加WHERE条件。)

或者,您可以在一个查询中获取所有内容并在客户端上解析结果:

SELECT 1 AS resultset,
       t1.customer_id, t1.name, t2.dtime, t6.band_type, t7.dop, t5.lun, t2.rpt
FROM
customer AS t1
Inner Join report AS t2 ON t1.customer_id = t2.customer_id
Inner Join employee AS t5 ON t5.employee_id = t2.employee_id
Inner Join band_type AS t6 ON t6.band_type_id = t2.band_type_id
Inner Join dop AS t7 ON t7.dop_id = t2.dop_id
WHERE
t2.rpt_type = 'daily' AND
t2.tmstamp >= date_sub(curdate(), interval 1 month) AND
t2.tmstamp <= curdate() AND
t1.customer_id = ''
UNION ALL
SELECT 2 AS resultset,
       t1.customer_id, t1.name, t2.dtime, t6.band_type, t7.dop, t5.lun, t2.rpt
FROM
customer AS t1
Inner Join report AS t2 ON t1.customer_id = t2.customer_id
Inner Join employee AS t5 ON t5.employee_id = t2.employee_id
Inner Join band_type AS t6 ON t6.band_type_id = t2.band_type_id
Inner Join dop AS t7 ON t7.dop_id = t2.dop_id
WHERE
t2.tmstamp >= '$date 00:00:00' AND
t2.tmstamp <= '$date 23:59:59' AND
t1.customer_id = '' AND
t2.deleted =  '0'
SELECT 3 AS resultset,
       t1.customer_id, t1.name, t2.dtime, t6.band_type, t7.dop, t5.lun, t2.rpt
FROM
customer AS t1
Inner Join report AS t2 ON t1.customer_id = t2.customer_id
Inner Join employee AS t5 ON t5.employee_id = t2.employee_id
Inner Join band_type AS t6 ON t6.band_type_id = t2.band_type_id
Inner Join dop AS t7 ON t7.dop_id = t2.dop_id
WHERE
t2.stamp >= date_sub(now(), interval 1 day) AND
t1.customer_id = '' AND
t2.band_type = '' AND
t2.deleted = '0'

此处,所有3个结果集都作为单个结果集返回,并附加一个字段(resultset),以便区分它们。

当然你也可以创建一个这样的视图:

CREATE VIEW v_customers AS
SELECT t1.customer_id, t1.name, t2.dtime, t6.band_type, t7.dop, t5.lun, t2.rpt
FROM
customer AS t1
Inner Join report AS t2 ON t1.customer_id = t2.customer_id
Inner Join employee AS t5 ON t5.employee_id = t2.employee_id
Inner Join band_type AS t6 ON t6.band_type_id = t2.band_type_id
Inner Join dop AS t7 ON t7.dop_id = t2.dop_id


SELECT *
FROM   v_customers
WHERE
t2.rpt_type = 'daily' AND
t2.tmstamp >= date_sub(curdate(), interval 1 month) AND
t2.tmstamp <= curdate() AND
t1.customer_id = ''

等,但您仍需要复制选择列表。

P. S.您想要优化的是什么?这些时候计算机非常适合复制字符串。

答案 1 :(得分:0)

请参阅here

您有2个选项,构建动态SQL或使用coalesce选项。

我更喜欢后者(滚动中间向下链接到“Coalesce功能”

请注意,两个选项都有其强弱点

答案 2 :(得分:0)

您可能想要创建一个视图。