473,473 Members | 2,147 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

How to clean up this simple query?

I am continually amazed by SQL's ability to humble me ....

I have a toy query into a toy database that looks just like this:

SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid and fw.wid = w.id and w.id in (((((select distinct w.id
from w where w.x in ('a', 'b') )))))
GROUP BY [f].[f]
HAVING count(f.id) = (select count(id) from (((((select distinct w.id from w
where w.x in ('a', 'b') ))))));
The query works and I am basically happy with it as it is, except it
contains the redundant string:

((((select distinct w.id from w where w.x in ('a', 'b'))))

duplicated precisely (I have marked it out with a few extra parens for easy
reading).
I need to do this query at runtime and would prefer not to do it twice ...
it just seems sloppy.

How can I eliminate the redundancy, perhaps by performing this query once
and storing the value to use a second time? Or does the optimizer do this
for me?

IOW, how can I do something like X = ((((select distinct w.id from w where
w.x in ('a', 'b')))), and then use X in place of the second evaluation of
this expression?

Thanks much.

Prefer reply to NG as my usual GMAIL account is flakey right now.

Thank you

RDeW

Nov 13 '05 #1
7 1899
You basically have 2 choices with SQL. You either duplciate the expression in
the query or you perform a query of a query to eliminate the duplication. In
either case, you're hoping the optimizer can do a good job with what you give
it, and the only way to find out for sure is to try it and/or look at a query
execution plan generated by the SQL processor.

On Sun, 28 Nov 2004 22:14:30 -0800, "Riley DeWiley" <ri***********@gmail.com>
wrote:
I am continually amazed by SQL's ability to humble me ....

I have a toy query into a toy database that looks just like this:

SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid and fw.wid = w.id and w.id in (((((select distinct w.id
from w where w.x in ('a', 'b') )))))
GROUP BY [f].[f]
HAVING count(f.id) = (select count(id) from (((((select distinct w.id from w
where w.x in ('a', 'b') ))))));
The query works and I am basically happy with it as it is, except it
contains the redundant string:

((((select distinct w.id from w where w.x in ('a', 'b'))))

duplicated precisely (I have marked it out with a few extra parens for easy
reading).
I need to do this query at runtime and would prefer not to do it twice ...
it just seems sloppy.

How can I eliminate the redundancy, perhaps by performing this query once
and storing the value to use a second time? Or does the optimizer do this
for me?

IOW, how can I do something like X = ((((select distinct w.id from w where
w.x in ('a', 'b')))), and then use X in place of the second evaluation of
this expression?

Thanks much.

Prefer reply to NG as my usual GMAIL account is flakey right now.

Thank you

RDeW


Nov 13 '05 #2
"Riley DeWiley" <ri***********@gmail.com> wrote in
news:10*************@corp.supernews.com:
I am continually amazed by SQL's ability to humble me ....

I have a toy query into a toy database that looks just like this:

SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid and fw.wid = w.id and w.id in (((((select distinct
w.id from w where w.x in ('a', 'b') )))))
GROUP BY [f].[f]
HAVING count(f.id) = (select count(id) from (((((select distinct w.id
from w where w.x in ('a', 'b') ))))));
The query works and I am basically happy with it as it is, except it
contains the redundant string:

((((select distinct w.id from w where w.x in ('a', 'b'))))

duplicated precisely (I have marked it out with a few extra parens for
easy reading).
I need to do this query at runtime and would prefer not to do it twice
... it just seems sloppy.

How can I eliminate the redundancy, perhaps by performing this query
once and storing the value to use a second time? Or does the optimizer
do this for me?

IOW, how can I do something like X = ((((select distinct w.id from w
where w.x in ('a', 'b')))), and then use X in place of the second
evaluation of this expression?

Thanks much.

Prefer reply to NG as my usual GMAIL account is flakey right now.

Thank you

RDeW


I can't think of any way to get rid of that "reduntant string". If the
optimizer can re-use that duplicate part is depending on what database
product you are using... (Don't expect too much.)

But there are some things you can do to simplify your query, and probably
improve performance a little.

Take a look at the first, "main" WHERE-clause:
WHERE f.id = fw.fid
and fw.wid = w.id
and w.id in (select distinct w.id
from w
where w.x in ('a', 'b'))

DISTINCT doesn't make any sense here. Remove it and you'll have
WHERE f.id = fw.fid
and fw.wid = w.id
and w.id in (select w.id
from w
where w.x in ('a', 'b'))
Then take a closer look at the HAVING-clause:
HAVING count(f.id) = (select count(id)
from (select distinct w.id
from w
where w.x in ('a', 'b')))

This can easily be rewritten as:
HAVING count(f.id) = (select count(distinct id)
from w
where w.x in ('a', 'b'))
Now your query is as:
SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid
and fw.wid = w.id
and w.id in (select w.id
from w
where w.x in ('a', 'b'))
GROUP BY "f"."f"
HAVING count(f.id) = (select count(distinct id)
from w
where w.x in ('a', 'b'))
If you know some details about the data, like unique constraints, you can
make the query even better. For example if the table w's id column is
unique, you can rewrite the query as:
SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid
and fw.wid = w.id
and w.x in ('a', 'b'))
GROUP BY "f"."f"
HAVING count(f.id) = (select count(distinct id)
from w
where w.x in ('a', 'b'))
HTH,
Jarl
Nov 13 '05 #3
Riley DeWiley wrote:
I am continually amazed by SQL's ability to humble me ....

I have a toy query into a toy database that looks just like this:

SELECT [f].[f]
FROM f, fw, w
WHERE f.id = fw.fid and fw.wid = w.id and w.id in (((((select distinct w.id
from w where w.x in ('a', 'b') )))))
GROUP BY [f].[f]
HAVING count(f.id) = (select count(id) from (((((select distinct w.id from w
where w.x in ('a', 'b') ))))));
The query works and I am basically happy with it as it is, except it
contains the redundant string:


My guess is that it is just Access that fouls up the representation of
the query. The optimizer in Jet will not evaluate this twice, I think.
You could try to store it as a separate query, but I can't tell if that
will expedite or hamper the query engine.
--
Bas Cost Budde, Holland
http://www.heuveltop.nl/BasCB/msac_index.html
I prefer human mail above automated so in my address
replace the queue with a tea
Nov 13 '05 #4
1) Please post DDL, so that people do not have to guess what the keys,
constraints, declarative referential integrity, datatypes, etc. In
your schema are. Sample data is also a good idea, along with clear
specifications.

2) Never name a column and a table the same thing. It is legal but
confusing and shows you have no data model -- a table is a set of
things and a column is a scalar, so you have confused a forest and a
tree.

3) Use and only one name for a column. You seem to be suffering from
the "magical, universal id" sdyndrome where the data element inherits
a table name when it is used somewhere else. Please read any book on
data modeling or ISO-11179 so you'll stop destroying your data
dictionary.

4) Why do think that excess parentheses will make the code easier to
read and maintain? It is not true. Why did you use needless
proprietary square brackets on names?

5) I am going to make a guess that the assorted "id" columns were
supposed to be named for a particular data element instead of a vague
universal attribute. I am going to use silly, but readable names for
tables. First hack:

SELECT Foobar.f
FROM Foobar AS F,
FooWoop AS FW,
Woop AS W
WHERE F.fid = FW.fid
AND FW.wid = W.wid
AND W.wid IN (SELECT W.wid
FROM Woop
WHERE x IN ('a', 'b'))
GROUP BY Foobar.f
HAVING COUNT(F.fid)
= (SELECT COUNT(DISTINCT W.wid)
FROM Woop
WHERE x IN ('a', 'b'));

This is gets rid of some of the query nesting. But since we have no
specs and no DDL, who knows??
How can I eliminate the redundancy, ... <<


1) Put it in a WITH clause, if you have an SQL that has implemented
that feature.

2) Let the optimizer handle it

3) Flatten out the query and get rid of the subqueries:

SELECT Foobar.f
FROM Foobar AS F,
FooWoop AS FW,
Woop AS W
WHERE F.fid = FW.fid
AND FW.wid = W.wid
AND W.x IN ('a', 'b')
GROUP BY Foobar.f
HAVING COUNT(F.fid)
= (SELECT COUNT(DISTINCT W.wid)
FROM Woop
WHERE x IN ('a', 'b'));

I am bothered by a COUNT(DISTINCT) on an idenrtifier column since it
shoudl be redundant. but without DDL, you knows??
Nov 13 '05 #5
AK
you haven't spe4cified RDBMS / version.
In general, google for "subquery factoring clause" / "WITH clause"
Nov 13 '05 #6
Just try the below query

select f.f
from f, fw, (select distinct w.id from w where w.x in ('a','b')) MyW
where f.id = fw.fid and
fw.wid = MyW.id
group by f.f
having count(f.id) = (select count(id) from MyW);
I haven't tested it.

Nov 13 '05 #7

"--CELKO--" <jc*******@earthlink.net> wrote in message
news:18*************************@posting.google.co m...
<deletia>


Whatever. I am still thrashing over here. What I am looking for is an
implementation of the hangar problem in which the hangar and pilot tables
are joined by a junction table. I am building my hangar-analogue table on
the fly through a query into another table, all this in a db where the
"hangar" table is joined N:N with the "pilot" table through a bridge.

Make any sense? I think I can figure it out in about another three days or
so.

RDeW
Nov 13 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Craig Thomson | last post by:
I was wondering what people do with text provided by the user in a form. Some cleaning needs to be done at some stage if you are going to be putting it in a database or displaying it etc. But when...
7
by: Creative Acceleration | last post by:
Hi all, I need to convert the Query Strings into Clean URLs, Found some articles on PHP and Apache server.. How do we it them with ASP ?? Thanks Kart
2
by: Mrs Howl | last post by:
I have a query that just reads one table and appends to an output table, one-for-one. No criteria. It's not a Total query (i.e. no group by). It normally run run in minutes, but gets horribly...
10
by: lallous | last post by:
Hello, This question was asked in comp.lang.c++ and the answers involved the use of objects whose destructors are automatically called when getting out of scope, however I was expecting...
4
by: Rick | last post by:
Hello, Below I create a static instance of an object, works well. public static BasicCounter GlobalCounter = new BasicCounter("GlobalCounter"); private void Page_Load(object sender,...
5
by: Rob | last post by:
I have a simple application consisting of about 4 forms and a few db connections... I would like to make sure that I have done proper clean up when the user exits the application. For all...
1
by: KevinGPO | last post by:
I got ASP code (VBScript mixed with HTML & Javascript) and am looking for a clean/tidy program to clean up my code. Should I use Dreamweaver cleanup, tool?
4
by: arak123 | last post by:
consider the following oversimplified and fictional code public void CreateInvoices(Invoice invoices) { IDbCommand command=Util.CreateDbCommand(); foreach(Invoice invoice in invoices) //lets...
1
by: sarahbanker | last post by:
ok, so I've inherited a nightmare of an Access 03 database, and trying to clean up the admin and maintainence side of it. It's being used as a tool to provide revised credit card limits based on...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.