dbTalk Databases Forums  

Intermediate values in insert statement

comp.databases.mysql comp.databases.mysql


Discuss Intermediate values in insert statement in the comp.databases.mysql forum.



Reply
 
Thread Tools Display Modes
  #11  
Old   
Captain Paralytic
 
Posts: n/a

Default Re: Intermediate values in insert statement - 01-19-2012 , 05:23 AM






On Jan 18, 5:03*pm, Dvd Avins <dvdav... (AT) pobox (DOT) com> wrote:
Quote:
Something of this form:

INSERT INTO c SELECT
* a.f AS f,
* a.x * a.r / b.r AS x,
* a.y * a.r / b.r AS y,
* a.z * a.r / b.r AS z
FROM a, b
WHERE a.g != "p" AND b.g = "p" AND b.f = a.f

It's actually more involved, but that is the essence. I would like to only calculate a.r / b.r once for each row. The real situation's calculations are sufficiently intensive that a subquery would be better than running theform above.

INSERT INTO c SELECT
* a.f AS f,
* a.x * t.r AS x,
* a.y * t.r AS y,
* a.z * t.r AS z
FROM a, (SELECT
* * a.f AS f,
* * a.r / b.r AS r
* FROM a, b
* WHERE a.g != "p" AND b.g = "p" and a.f = b.f) t
WHERE t.f = a.f

Does that make sense? Does SQL syntax require b to be listed in the outerFROM clause?
I urge you to use explicit JOINs rather than implicit comma joins.
You'll save yourself a lot of grief in the future and your intentions
will be easier to understand as it separates JOIN criteria from
SELECTion criteria.

Now the subquery is certainly the proper supported way to achieve what
you want. As Erick points out, when the calculation is complicated,
there are sound maintenance reasons for coding it only once.

There is another way that this can be achieved. It is specifically
advised against in the manual, but I have always found it to work.

Your query would be re-written as:
INSERT INTO c SELECT
a.f AS f,
a.x * (@tmp:=(a.r / b.r)) AS x,
a.y * @tmp AS y,
a.z * @tmp AS z
FROM a
JOIN b USING(f)
WHERE a.g != "p" AND b.g = "p"

Notes on the above query:
1) All the brackets used in the assignment of eh variable @tmp are not
strictly necessary. I use them to keep my intentions clear.
2) I have taken the liberty of changing the implicit join to an
explicit one. This is not actually required for the query to work.
3) Whilst I have always found this to work, you should read the
paragraph beginning: "As a general rule," on the page
http://dev.mysql.com/doc/refman/5.6/...variables.html, which I
alluded to above.

Reply With Quote
  #12  
Old   
Axel Schwenke
 
Posts: n/a

Default Re: Intermediate values in insert statement - 01-19-2012 , 06:42 AM






Captain Paralytic <paul_lautman (AT) yahoo (DOT) com> wrote:

Quote:
There is another way that this can be achieved. It is specifically
advised against in the manual, but I have always found it to work.

INSERT INTO c SELECT
a.f AS f,
a.x * (@tmp:=(a.r / b.r)) AS x,
a.y * @tmp AS y,
a.z * @tmp AS z
FROM a
JOIN b USING(f)
WHERE a.g != "p" AND b.g = "p"
I don't know what your business is, but relying on undefined
behavior can sometimes result in the termination of your contract.
Or your life

If we assume for a moment that there are /good/ reasons to
single out the calculation of (a.r/b.r) then we can do it
with a "derived table" subquery like so:

INSERT INTO c (f, x, y, z)
SELECT f, x*tmp, y*tmp, z*tmp
FROM (
SELECT a.f, a.x, a.y, a.z, a.r/b.r AS tmp
FROM a JOIN b USING(f)
WHERE a.g != "p" AND b.g = "p"
) AS t1

This has the advantage of being SQL compliant and does not rely
on undefined behavior. However I severely doubt that the runtime
behavior is any better than that of the original query. Also it's
not exactly easier to read :/

Note: instead of aliasing the selected columns for mapping to
columns in c, I rather used an explicite column list for the
INSERT statement. This is a matter of taste.


XL

Reply With Quote
  #13  
Old   
Captain Paralytic
 
Posts: n/a

Default Re: Intermediate values in insert statement - 01-19-2012 , 07:02 AM



On Jan 19, 12:42*pm, Axel Schwenke <axel.schwe... (AT) gmx (DOT) de> wrote:
Quote:
I don't know what your business is, but relying on undefined
behavior can sometimes result in the termination of your contract.
Or your life

Yes, Axel, did you bother to read my whole post?

I said: "Now the subquery is certainly the proper supported way to
achieve what you want.", which is a more concise way of saying "This
has the advantage of being SQL compliant and does not..."

I also carefully included: "It is specifically advised against in the
manual" and went on to include the precise reference in the manual
itself.

So I think your post is rather superfluous.

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.