tags:

views:

53

answers:

3

I have about 4 or 5 different queries that are all exactly like with the exception of what is contained in the WHERE clause. For example, these are reports that operate by date so one report uses a date of Now() and the other reports use dates by month and 15 days. All of the fields are exactly the same. Is there a way to combine these into a single query and just change the data in the WHERE clause on the fly? Or some other solution??

Thanks


OK Guys, thanks for the replies. Here are the actual queries. Please notice that the where clause is the only thing that differs and I really hate having to write another query that is almost exactly alike whenever I need to add a new report.

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'
A: 

Use OR or UNION 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

Update:

If you want three resultsets, you'll need three queries, and if you have three queries, you have three SELECT lists.

You can compose your queries within the application (you create SELECT list once and just add a WHERE condition).

Alternatively, you can get everything in a single query and parse the results on the client:

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'

Here, all 3 resultsets are returned as a single resultset, with an additional field (resultset) that allows to distinguish between them.

Of course you can also create a view like this:

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 = ''

, etc., but you'll still need to copy a select list.

P. S. What exactly is that you want to optimize? Computers these times are very good in copying strings.

Quassnoi
Hi Quassnoi. I don't think I can use OR because all of these different reports can be compiled based on my criteria. I mean that all three different queries will produce results. It's just what the user wants to see. Can I still use UNION ALL for this?
Can't say until I see your queries. As for now, the question is too vague.
Quassnoi
Ok, brb.. I will post two of them.. gimme a sec.
Hi Quassnoi, thanks for the update. I truly appreciate the effort. I have never used UNION ALL. If I were to use this, I'm not going to get a lot of null values, am I? I have had experiences in the past with UNION ALL where my result set was way off. I'd hate to have to try and troubleshoot this. You're sure this will work?
In reality you are still forced to copy/paste the complete query again... Also you are forced to query the recordset three times to get all results and then add a subsequent where clause for which result set you want... However in case of reports, speed might not be an issue
Rippo
Exactly. I am seeing the same thing. I want to try and cut down on my application code class. It is getting quite unmanageable with all the SQL. erikkallen just offered a suggestion to create a view. I'm not bog on views, although I probably should be but could I use a view and a where clause against it?
A: 

see here

You have 2 options, build dynamic SQL or use the coalesce option.

I prefer the later (scroll half way down link to "the Coalesce function"

Be warned though that both options have their strong/weak points

Rippo
Hi Rippo, thanks for the link. I'm going there now. Also, I posted the actual queries above if you want to have a look.
Ignore me Jim, in my haste I posted a solution in MSQQL...I think dynamic SQL is still possible though, albeit a bit ugly..see http://forums.mysql.com/read.php?60,3127,6260#msg-6260
Rippo
unless of course if you substitute coalease with isNull
Rippo
:) I noticed that the dynamic approach is ugly but it may be what I need. What is happening is that the client is requesting more reports and I just find myself having to rewwrite the exact same queries over and over again.
I agree! In some instances like reports that only get used now and again then dynamic SQL is OK... however I would not run dynamic SQL on a heavily used request...Let me now if the Isnull approach works as I have used this in MSSQL before with no problems. However your against your queries this might not work!
Rippo
Hey Rippo, thanks again. Let me ask you. I've used coalease before but I'm unsure how to use it in this case. What exactly would be null? Also, Quassnoi below has offered a solution using UNION ALL. What is your opinion of that?
I think in you queries the isnull/coalese option is going to be difficult because of the "tmstamp" where clauses.Dynamic sql might give you want you want...
Rippo
Ok, I can do that. Let me ask you this. Is creating a view an option? Can I use a view and use a WHERE clause against it?
I would build a view any way as it simplifies the joins, but the where clause would still need to be dynanic
Rippo
Ok, I'm going to go the dynamic route. Thanks so much for the help Rippo!
No worries... You may get better answers over the next 24 hours!!!
Rippo
Thanks again Rippo.
A: 

You might want to create a view.

erikkallen
Sure, views are good but I'd still have to write the same query for as many times as I need it, right? Are you talking about creating a view for the part that is the same and then using my where clause against the view?
the view would help to simplify the query as you could doselect * from view1 where .... instead ofselect * from t1 inner join t2 etcHowever you would still need some dynamic sql for the where part...
Rippo