Scott Haneda <[EMAIL PROTECTED]> wrote on 11/16/2005 05:44:05 AM:
> Some of these tables are rather large, I would put the schema in there,
but
> I think it just adds to the mess.
>
> Tables
> `users` field id is auto inc pk
> `orders` field id is auto inc pk
> `products` field id is auto inc pk
>
> `order_items` field order_id is the key for hooking up order_items to
> orders, also, in `order_items` I store order_id which comes from the
users
> table. I also have product_id which is how the product is related to an
> order item.
>
> Some of the products can be marked as instock or out of stock, with
> products.ship_status = 1 or 0
>
> What I need, is a select, that grabs all order records, joined on the
> order_items for that order, where the products.ship_status is = 1. If
ANY
> of the products do not have a ship_status of 1, it should not be include
in
> the results.
>
> I also need to further limit this based on a date field in the orders
table,
> which can be a date in the future, or NULL, it is called
delayed_ship_date.
> So the limit is WHERE delayed_ship_date is within 13 days of NOW() OR
where
> delayed_ship_date is null.
>
> Finally, only where the order status is either 'pre-order' or 'delayed'
>
> To better explain, we have orders in a system, each order can have many
> order items. However, each of the order items may or may not be in
stock.
> I only want to see orders that can be fulfilled. I further want to only
see
> orders where the delayed_ship_date is within 13 days of today, or where
it
> is NULL, in which case, it means the user wants the stuff as soon as
> possible.
>
> I know it is a little strange, we are dealing with perishables, so
random
> shipping dates do not always apply. I seem to be able to get this to
sort
> of work, but I end up getting back thousands of records where I want
just
> one for the order, not one for each and ever order item.
>
> --
> -------------------------------------------------------------
> Scott Haneda Tel: 415.898.2602
> <http://www.newgeo.com> Novato, CA U.S.A.
>
>
## First, let's identify which products have a ship_status=1
CREATE TEMPORARY TABLE tmpProducts (KEY(id)) SELECT id
FROM products p
WHERE ship_status=1;
## Now let's make a list of all orders that meet your date criteria and
shipping status
CREATE TEMPORARY TABLE tmpOrders (KEY(ID)) (
SELECT id
FROM orders
WHERE delayed_ship_date < = NOW() + INTERVAL 13 DAY
AND status IN ('pre-order','delayed')
) UNION (
SELECT id
FROM orders
WHERE delayed_ship_date is NULL
AND status IN ('pre-order','delayed')
);
## Let's combine those tables with order_items to single out only those
orders that
## not only meet your order status and date criteria but also have
products
## whose ship_status=1.
CREATE TEMPORARY TABLE tmpBackorders (KEY(ID)) SELECT DISTINCT ord.id
FROM tmpOrders ord
INNER JOIN order_items oi
on oi.order_id = ord.id
INNER JOIN tmpProducts tp
on tp.id = oi.product_id;
## now you have a list of all of the backorders that should be shipped
ASAP or within 13 days
## You can use that list to get all of the information for each order back
from the
## `orders` table
SELECT o.*
FROM orders o
inner join tmpBackorders b
on b.id = o.id
order by o.delayed_ship_date;
## Last thing: the database is not your mommy. Clean up before you leave
the session
DROP TEMPORARY TABLE tmpBackorders, tmpOrders, tmpProducts;
Make sense? I split it up this way for speed. To do this all in one
complex statement _IS_ possible (I know I can write a single statement to
return the same results) but you didn't sound like you had an hour to wait
on that query to finish. The extra time it would have taken to process the
single-statement version has to do with how many JOINs were going to be
used and how much of your existing data you would wind up throwing out
anyway. By pre-limiting ourselves to selected subsets of your data, we
drastically minimize the number of comparisons necessary to compute
tmpBackorders thus reducing how long it takes to give you the desired
information from the orders table.
Shawn Green
Database Administrator
Unimin Corporation - Spruce Pine