SQL query - comparing values to show availability - php

Just getting to grips with some more advance sql queries and a bit stuck with one of them. I’ve been working on a small cinema project that allows user to book seats for upcoming productions.
In a table for chairs, I’ve created a query so that checkboxes are created on all of the chairs within a particular cinema area. However, I now need to add some sort of functionality to show chair availability i.e. whether one has already been booked by a previous order.

select * from `chairs` c
left outer join `booki1` b on b.`seatno`=c.`seatno`
left outer join `shows` s on s.`ddate`=b.`ddate`
left outer join `area` a on a.`name`=c.`area`
where (
c.`area` like '{$_SESSION['Area']}' and
s.`ddate` like '{$_SESSION['DDate']}' and
s.`ttime` like '{$_SESSION['TTime']}}'
);
Very hastily put together and totally untested, but you need to join the tables using suitable keys.

Related

Joins not working in SQL Code not joining corectly strange errors occurring

I have been trying to get this code working for almost six hours an I have done almost six hours worth of research.
Originally this code was to be outputted from a database through PHP to a CSV file..
All I am trying to do is have three different tables and have them all joined together by their order_ID
Every time I keep trying to do this in PHP my admin either the code comes out weird in the output is not joining correctly or is giving some sort of strange error. Any help that anyone could figure out what is going on with this would be greatly appreciated
SELECT
oc_order.store_url,
oc_order.order_id,
oc_order.firstname,
oc_order.lastname,
oc_order.email,
oc_order_option.order_id,
oc_order_option.name,
oc_order_option.value,
oc_order_product.order_id,
oc_order_product.name,
oc_order_product.model,
oc_order_product.quantity
FROM oc_order, oc_order_option , oc_order_product
ORDER BY oc_order.order_id,oc_order_option.order_id,oc_order_product.order_id
As mentioned, you are missing your ON clauses. When you are using multiple tables in a SQL query, you have your LEFT table (first table in from clause) being JOINed to the second (right table). The "ON" clause tells how table 1 is related to table 2. And in your case, you have a table 3. Is this a relationship between table 1 to 3 or from table 2 to 3. I will update the query, you will need to fill in the blanks a bit since you have not shown structures. Also, using table aliases makes code more readable, especially if table names get long. You'll see in a moment.
SELECT
o.store_url,
o.order_id,
o.firstname,
o.lastname,
o.email,
oOp.order_id,
oOp.name,
oOp.value,
p.order_id,
p.name,
p.model,
p.quantity
FROM
oc_order o
JOIN oc_order_option oOp
on o.order_id = oOp.order_id
JOIN oc_order_product p
on o.order_id = p.order_id
ORDER BY
o.order_id
Notice the abbreviated aliases for the table names "o" for oc_orders, "oOp" for oc_order_option and "p" for oc_order_product
Again, YOU need to confirm the "ON" clauses on the left-table is associated with the right table. I have worked with manufacturing in the past and have seen that someone orders. Purchases a product, and that product has options, so Is there something on the order's detail line for the specific product that has an ID to the order OPTIONS table. That is where you probably need to focus. Again, other systems I have had, would have had a hierarchy something like
Order
Customer (who ordered)
OrderDetails (what of multiple products were ordered)
Product ( per orderDetail, what was the product)
ProductOption (color,size,etc)
See the hierarchical representation? In this scenario, you dont go just from Order table to the Product option. You have to get to the details to the product to the product's option. Anyway, HTH

Performance: Get and group productdetails from 5 tables in a single query instead of multiples?

Currently I'm developing a background cms for an online shop.
I split the tables as follow in my database:
-products
-productdetails (descrition...)
-productimages
-product variants (colors..)
-product cross selling
Now on the product edit page i need to fetch all data for a single product.
So my question is how i can get those details more efficient then make 3-5 database calls.
Or would the processing with php be less efficient then make those 3-5 calls ?
At the moment the query looks like that:
SELECT
pr.id, pr.categorieid, pr.itemnumber, pr.barcode, pr.price, pr.weight, pr.gender, pr.manufracture, pr.fsk18, pr.condition, pc.id AS pcid, pc.productcrossid, pc.sort, pd.productname,
pd.productdesc, pd.additional, pd.linktitle, pd.metatitle, pd.metadesc, pd.urlkeywords, pi.id AS piid, pi.wichimage, pi.variantid, pi.image, pi.imagealt, pv.id AS pvid, pv.variant,
pv.variantvalue, pv.sku, pv.price AS pvprice, pv.weight AS pvweight, pv.stock, pv.special
FROM
products pr
LEFT JOIN
productcross as pc
ON pr.id = pc.productid
LEFT JOIN
productdetails as pd
ON pr.id = pd.productid
LEFT JOIN
productimage as pi
ON pr.id = pi.productid AND pd.lang = pi.lang
LEFT JOIN
productvariants as pv
ON pr.id = pv.productid
WHERE
pr.id = :id
ORDER BY pd.lang ASC
As result i recieve many rows, because of the left join each value get joined with the rows i joined before.
The problem is there are dynamic many rows for cross selling, variants, images, so it can be random if variants or images are more (else i could group them atleast because each variant can get an own image, but there can be also more images then variants)
Products 1 row, productdetails according to how many languages are used, most likely 3.
Edit: According to Explain and the indexes i set, the performance of this single query is very good.
Edit:
According Paul Spiegel i tryed using GROUP_CONCAT
SELECT
pr.id, pr.categorieid, pr.itemnumber, pr.barcode, pr.price, pr.weight, pr.gender, pr.manufracture, pr.fsk18, pr.condition, pc.id AS pcid, pc.productcrossid, pc.sort, pd.productname,
pd.productdesc, pd.additional, pd.linktitle, pd.metatitle, pd.metadesc, pd.urlkeywords
FROM
products pr
LEFT JOIN
productsdetails as pd
ON pr.id = pd.productid
LEFT JOIN (
SELECT
GROUP_CONCAT(productcrossid) AS pcproductcrossid, GROUP_CONCAT(sort) AS pcsort, GROUP_CONCAT(id) AS pcid, productid
FROM productscross
WHERE productid = :id
) pc
ON pr.id = pc.productid
WHERE
pr.id = :id
ORDER BY pd.lang ASC
As result i recieve many rows, because of the left join each value get joined with the rows i joined before.
That's not what LEFT means.
X JOIN Y ON ... delivers rows that show up on both X and Y.
X LEFT JOIN Y ON ... delivers all the rows of X even if there is no matching row (or rows) in Y.
You might get "many rows" because the relationship is "1:many". Think of Classes JOIN Students With JOIN you get multiple rows per Class (one per student), except for any classes without any students. With LEFT JOIN, you additionally get a row for any Class with no students.
Your query with products will be a huge explosion of rows. All products, expanded by multiple details by multiple images, etc. It will be a mess.
In the EXPLAIN, multiply the numbers in the "Rows" column -- that will be a crude metric of how big the result set will be.
Use one query to get the images; another to get the colors; etc. Use JOIN (or LEFT JOIN only when needed.
GROUP_CONCAT() is handy sometimes. It might be useful to list the "colors". But for "images", you would then have to split it up so you can build multiple <img..> tags. That's rather easy to do, but it is extra work.
It is usually 'wrong' to have 1:1 mapping between tables. In such cases, why not have a single table?
Do not fear 3-5 queries. We are talking milliseconds. The rendering of the page is likely to take several times as long as the SELECTs. I often have several dozen queries to build a web page, yet I am satisfied with the performance. And, yes, I ascribe to the notion of putting all the info about one 'product' on the page at once (when practical). It's much better than having to click here to get the colors and click there to see the images, etc.
Rather than hitting so many query's you can refer to the concept which is known as flat tables in magento.
The logic behind using this concept is that what ever important data which is required to be show on the front end is stored in single table itself as well as the data is stored in there prescriptive tables.
So while querying you just need to pick the data from that flat table itself rather than querying to multiple tables and increasing the query execution time.
For reference Please check out the below link,Hope this helps.
Visit http://excellencemagentoblog.com/blog/2015/06/10/magento-flat-tables/
I do know the question is not regarding Magento but you can build your own logic to achieve this mechanism.

MYSQL combining results into single item for display

I'm currently having an issue where I run a query on multiple tables getting the results, but they are all being considered independent. I've tried a couple ways of combining them, but because my SQL knowledge is limited I can't seem to get what I want to happen.
SELECT DISTINCT t.*, s.quantity, s.rrp, ts.thumbnail, ts.bigpic, t.rating
FROM tyres t
INNER JOIN stocklevels s
ON t.stockcode = s.stockcode
LEFT JOIN tyre_treads ts
ON t.treadid = ts.recid
LEFT JOIN reseller r
ON s.city=r.recid
WHERE s.quantity> 0 AND s.rrp > 0
I've tried adding GROUP BY t.recid and a couple other basic solutions but this doesn't seem to work. I've added a couple images which might help.
As you can see the bottom Toyo tyres are the same, just with varying cities and quantities.
Here they are on the website.
I'm wanting to combine they so that they say minimum 6 in stock and shows only once on the site.
As long as there is at least one column in your SQK resukt, which contains different values (like city in your example for "the same" tire, group by won't work. You must adapt your SQL statement in a way, that it only picks columns with the same values. Especially, you should remove the t.* from your sql and name all columns (You then will not need the distinct anymore).
Then, you sum over quantity to get the combined value for this column as wanted.
SELECT r.recid, sum(s.quantity), s.rrp, ts.thumbnail, ts.bigpic, t.rating
FROM tyres t
INNER JOIN stocklevels s
ON t.stockcode = s.stockcode
LEFT JOIN tyre_treads ts
ON t.treadid = ts.recid
LEFT JOIN reseller r
ON s.city=r.recid
WHERE s.quantity> 0 AND s.rrp > 0
GROUP BY recid

How to select from / join 5 tables using PHP and mySQL

I'm trying to build a review record based on fields from 5 tables:
I've marked all the columns I need, but for the moment I'm just retrieving all of the user_rating table.
Here's what I have so far:
SELECT DISTINCT user_rating.*, whiskey.name, user_notes.overall, users.image, user_rate.rate_number
FROM user_rating
LEFT JOIN whiskey ON whiskey.id = user_rating.whiskeyid
LEFT JOIN users ON users.username = user_rating.username
LEFT JOIN user_notes ON user_notes.username = user_rating.username AND user_rating.whiskeyid = user_notes.whiskey_id
LEFT JOIN user_rate ON user_rate.whiskey_id = user_rating.whiskeyid AND user_rate.username = user_rating.username
ORDER BY user_rating.id DESC
At first I thought this was giving me the results I wanted but then I noticed I was getting multiple rows as well as too many null fields. Any help would be greatly appreciated.
Edit:
By multiple rows I mean duplicate rows. Also, I am aware that a left join produces null values on the right side of the join. What I meant to say is that I'm getting more null values than I should be as the data is within the database.
To clarify, I'm trying to create a list of recent reviews with the most recent listed first. Each review consists of a username, 11 categories (each one is an integer value), overall rating (int value), notes (string), image (URL), and whiskey name (string).
1) You can't be getting multiple SAME rows, since you use DISTINCT. (by multiple do you mean duplicate?)
2) You get null fields because you are using LEFT JOIN and your tables cannot be joined (some "ON clause" cannot be evaluated as true)
It turns out that there was nothing wrong with my query. The person whose database I'm using isn't maintaining it so there are several reviews for the same product and user where only the overall rating is different. Also, there are many reviews on products that don't even exist. I should've looked at the database closer to begin with as deleting all of the erroneous rows solved my problem. Thanks for all the input.

MySQL join returning redundant data

I am building an auction website. Right now, I am building the item description page, that has item details, as well as current bid history. My bids table has a FK of Item_id.
My current query looks something like this:
SELECT bids.Item_id, bids.User_email, bids.Bid_amount, products.*
FROM bids
INNER JOIN products
ON bids.Item_id=products.Item_id;
This returns all of the bid information I need - but also returns the item description for every bid row. I only need the product information once. Is it best to just use two queries on this?
Any help is appreciated
If you need the bids data separately from the products data, then you should use two queries.
One query cannot really be arrange to return different columns for different rows.
SELECT b.Item_id, b.User_email, b.Bid_amount, p.*
FROM bids b
INNER JOIN products p
ON b.Item_id=p.Item_id
WHERE p.Item_id=something;
This will not repeat products..

Categories