MySql Inner Join Query - mysql

I'm using mysql connector to connect visual basic with mysql,i m doing mysql query with 3 tables and i tried with inner join and the "normal mode" with the "normal mode" said not unique table/alias and with inner join the datagrid doesnt load anything,the three table are this ones
Order(N_Order,Date,Client Number)
Line_Order(N_Order,product_code,quantity)
Product(product_code,name,price)
and the mysql query with innerjoin is:
"SELECT c.name, COUNT( b.product_code ) AS cnt FROM order a " & _
"INNER JOIN line_order b ON a.number_order = b.number_order " & _
"INNER JOIN product c ON b.product_code = c.product_code " & _
"GROUP BY c.name " & _
"ORDER BY cnt DESC "
and the normal way is:
"SELECT product.name, COUNT( order_line.product_code ) AS cnt
FROM order, product, order_line where order.number_order = order_line.number_order
AND order_line.product_code = product.product_code
GROUP BY product.name
ORDER BY cnt DESC
LIMIT 0 , 5"
When i run the 2ยบ mysql query in phpmyadmin it works perfectly but when i run it in visual basic it gives me the error not unique tables alias/order i dont know what to do can someone help me please??

Put backticks ` around the table `order` as it conflicts with the reserved keyword in ORDER BY.

Its Solved it was from the datagridview size was too little for the data,2 hours on this because of the datagridview size,thanks guys for the help

Related

Excel VBA SQL Join Syntax Error

I am writing a sub that allows the user to select a Customer from a listbox. The selection is recorded as CustomerID (integer variable) and used to query an Access Database file. The sub should then output to an excel worksheet sales information about the specified customer, notably:
Order Date
OrderID
Total Order Cost (defined as qty sold * Price Sold)
The access file has 3 tables that I need: Customers, Orders, LineItems
My code below should join the customer ID to order ID fields, which is then joined against order ids, and order ids is joined on line items.
' Define SQL statement to get order info for selected product.
SQL = "SELECT O.OrderDate, COUNT(O.OrderID), SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost] " _
& "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems L " _
& "ON O.OrderID = L.OrderID)" _
& "WHERE O.CustomerID =" & CustomerID & " " _
& "GROUP BY O.OrderDate, O.OrderID" _
& "ORDER BY O.OrderDate"
I keep getting a "Syntax Error in FROM clause". Are my JOIN statements are correct? I have played around with the (), "", etc without success. I have checked and Table Names are correct (Orders, Customers, LineItems) field names are also spelled correctly.
I like to use an array and the Join method with a space delimiter. That makes sure I don't miss any spaces (which #McAdam133 pointed out that you did).
Dim aSql(1 To 6) As String
aSql(1) = "SELECT O.OrderDate, COUNT(O.OrderID), SUM([L.QuantityOrdered]*[L.QuotedPrice]) AS TotalCost"
aSql(2) = "FROM (Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)"
aSql(3) = "INNER JOIN LineItems L ON O.OrderID = L.OrderID"
aSql(4) = "WHERE C.CustomerID = " & CustomerID
aSql(5) = "GROUP BY O.OrderDate"
aSql(6) = "ORDER BY O.OrderDate"
Set rs = CurrentProject.Connection.Execute(Join(aSql, Space(1)))
Here's my advice for inner joins that don't work. Create a Query in Access and look at the SQL it generates. It may not be the prettiest SQL, but it may help you determine what's wrong. If you put Customers, Orders, and LineItems in a query window, draw your arrows if necessary (probably will be there by default), and put a couple of fields in there, Access will generate something like
SELECT Orders.OrderID, Orders.OrderDate, LineItems.QuantityOrdered, LineItems.QuotedPrice
FROM (Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID) INNER JOIN LineItems ON Orders.OrderID = LineItems.OrderID;
That doesn't group anything or use aliases, but it gives you a working statement. Then you can modify with aliases and groupings, testing it along the way.
From your example:
& "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
This line is good. You're joining Customers on Orders using the primary key from Customers and presumably a foreign key in Orders.
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _
I'm not sure what the first join is trying to accomplish, but as #OpiesDad commented it's not what you want. You've already successfully joined Customers and Orders in the first line, so you can take the result of that join and join it up to LineItems (aSql(3) above). The second join (to LineItems) looks fine.
You can join two tables on more than one field. Like if you had two tables of customers and you wanted to see if there is any overlap.
FROM Wholesale INNER JOIN Retail ON Wholesale.CustomerName = Retail.CustName AND Wholesale.State = Retail.StateOrProvince
Based on the structure you've shown, you have nicely unique primary keys in all your tables, so joining on more than one field isn't necessary.
Lastly, you're grouping on OrderID. It's not causing an error, but it's not doing anything either. You use OrderID in an aggregate function in the SELECT portion. You should aggregate the fields you want to aggregate and group by the fields you don't aggregate.
You must use AS when you create an alias for a table in your INNER JOIN's:
' Define SQL statement to get order info for selected product.
SQL = "SELECT O.OrderDate, COUNT(O.OrderID), SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost] " _
& "FROM (((Customers as C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _
& "ON O.OrderID = L.OrderID)" _
& "WHERE O.CustomerID =" & CustomerID & " " _
& "GROUP BY O.OrderDate, O.OrderID" _
& "ORDER BY O.OrderDate;"
To be sure, terminate the statement with ;.
The problem you are having is that the join you are trying to do doesn't make sense.
Let's first just get the relevant order and then add the line items as it will make the explanation simpler.
To do this, you want the SQL:
SELECT C.CustomerID, C.CustomerName, O.OrderID, O.OrderDate
FROM Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID
WHERE C.CustomerID = 15
ORDER By O.OrderDate
Note, this assumes that the customer you are looking for has ID 15.
This will give you a list of all orders in ascending order for the requested customer.
If you want the line items, then you need to link to this table as well:
SELECT C.CustomerID, C.CustomerName, O.OrderId, O.OrderDate
, SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost]
FROM ((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)
INNER JOIN LineItems L ON O.OrderID = L.OrderID)
WHERE C.CustomerID = 15
GROUP BY C.CustomerID, C.CustomerName, O.OrderID, O.OrderDate
ORDER BY O.OrderDate
This is likely the query you are looking for. The second INNER JOIN you had listed was superfluous and didn't make sense. You don't want to match the OrderID to the CustomerID, you want the list of orders that match that customer. The first INNER JOIN on C to O already creates this. The where clause limits the customer table to just the one customer.
To put this in your code, just replace the "15" with "CustomerID" from your form.
Also, per McAdam's comment, you are missing spaces in a couple of places. To fix this, I recommend putting all spaces as the beginning of the line so that you can make sure they are there (as is done below). The final code should look like this (removing the customer info from the output):
SQL = "SELECT O.OrderDate, O.OrderID" _
& ", SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost]" _
& " FROM ((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)" _
& " INNER JOIN LineItems L ON O.OrderID = L.OrderID)" _
& " WHERE O.CustomerID =" & CustomerID _
& " GROUP BY O.OrderDate, O.OrderID" _
& " ORDER BY O.OrderDate"
You also don't seem to actually want the count of orderIDs so I took that out as it also didn't make too much sense.

Built in Functions and Grouping is not working in Microsoft Access

I am trying to select from three tables using inner join in Microsoft Access. in one of the fields, i also need to select how many records did it return.
SELECT Person.FirstName, Person.LastName, Person.Phone,
Person.Email,Person.Address, Room.RoomNo, Room.Type, Building.Name,
Floor.Name,count(*) as result
FROM (Floor INNER JOIN (Building INNER JOIN
Room ON Building.BuildingID = Room.BuildingID) ON Floor.FloorNo =
Room.FloorNo) INNER JOIN (Person INNER JOIN Patient ON Person.Username =
Patient.Username) ON Room.RoomNo = Patient.RoomNo
WHERE (((Person.FirstName) Like "*" & [Forms]![search]![firstnameKey] & "*")
AND ((Person.LastName) Like "*" & [Forms]![search]![lastnameKey] & "*")) AND
(patient.status = 1)
GROUP BY Patient.username ;
Any time you have an aggregate function you'll have to group by the fields not being calculated. Just from looking at your select statement you are returning multiple fields, i.e: Person.Firstname, Person.Lastname etc. I believe you will have to group by those non-aggregated fields.
Sample Code:
SELECT Person.FirstName, Person.LastName, Person.Phone, Person.Email, Person.Address, Count(*) as Result <br>
From Table1 join table 2 -- etc <br>
WHERE a = b -- etc <BR>
GROUP BY Person.FirstName, Person.LastName, Person.Phone, Person.Email, Person.Address

mySQL two tables LEFT JOIN on multiple NULLS

I have a question regarding a two table join. In this case Table1 (booking table) and Table2 (Booking Entries).
I need a query to get all the rows from Table1 WHERE the member_id in Table2 (exists only here not in table1) and Vip_id in BOTH tables can be searched.
SELECT vb.* , DATE_FORMAT(vb.bookingdate, '%W %D %M') bookingdate, DATE_FORMAT(vb.bookingrsvp, '%W %D %M') bookingrsvp, concat(sl.state, ' - ', sl.store) store, sl.ADD1, sl.ADD2, sl.SUBURB, sl.PHONE , ve.vip_entry_leadid
FROM vip_booking vb
INNER JOIN storelocator sl ON (vb.storeid = sl.id )
LEFT JOIN vip_entries ve ON (vb.vipid = ve.vip_id AND ve.vip_entry_leadid = '" . $_GET["leadid"] . "')
WHERE vb.vipid = " . $_GET["vipid"] . "
AND DATE(vb.bookingdate) >= CURDATE()
AND ve.vip_entry_leadid IS NULL
AND ve.vip_id IS NULL
GROUP BY vb.storeid ORDER BY sl.state, sl.store
Basically what I am trying to achieve here is select ALL bookings from ALL Stores part of a particular VIP EVENT that the CURRENT LOGGED IN USER hasn't already had an entry too? If it was a single field ie. vip_entries.vip_id = vip_booking.vipid THEN that would be okm however a user can be in the entries table multiple times provided that it is a DIFFERENT event?
The above query works however I don't know if I have written it correctly as I would like to use joins and avoid sub-queries.
Can you post some sample data in the question please.
Your query appears to do a LEFT JOIN on vip_entries, and then checks for NULL in 2 fields to ensure no record is found (might be better to check the unique id field of vip_entries, if one exists). But you then bring back the value vip_entries.vip_entry_leadid which will always be null.
Further you are using GROUP BY store_id. This will bring back one row per store_id, but the other values will be from an undefined row for that store_id (in most databases this would fail). I suspect looking at your description you actually want to bring back one row per event / store id (which is probably a unique combination) in which case it would seem you do not need the GROUP BY.
The above query works however I don't know if I have written it correctly
Unfortunately, while preceding SQL works in MySQL, your query is not valid in ANSI SQL. Only GROUP BY column and aggregation function can be SELECTed
I would like to use joins and avoid sub-queries.
As far as I know without sub-queries, you can only fetch vb.storeid as follows
SELECT vb.storeid
FROM vip_booking vb
INNER JOIN storelocator sl ON (vb.storeid = sl.id )
LEFT JOIN vip_entries ve ON (vb.vipid = ve.vip_id AND ve.vip_entry_leadid = '$leadid')
WHERE vb.vipid = $vipid
AND DATE(vb.bookingdate) >= CURDATE()
AND ve.vip_entry_leadid IS NULL
AND ve.vip_id IS NULL
GROUP BY vb.storeid;
Proper SQL with sub-queries:
In my opinion Following query is formal SQL for what you want.
SELECT
vb.*,
DATE_FORMAT(vb.bookingdate, '%W %D %M') bookingdate,
DATE_FORMAT(vb.bookingrsvp, '%W %D %M') bookingrsvp,
CONCAT(sl.state, ' - ', sl.store) store,
sl.ADD1, sl.ADD2, sl.SUBURB, sl.PHONE , ve.vip_entry_leadid
FROM
(SELECT DISTINCT
vb.storeid
FROM
vip_booking vb
LEFT JOIN
vip_entries ve ON (vb.vipid = ve.vip_id AND ve.vip_entry_leadid = '" . $_GET["leadid"] . "'
WHERE
vb.vipid = " . $_GET["vipid"] . "
AND DATE(vb.bookingdate) >= CURDATE()
AND ve.vip_entry_leadid IS NULL
AND ve.vip_id IS NULL) x
INNER JOIN
storelocator sl ON (x.storeid = sl.id)
ORDER BY
sl.state, sl.store;

JDBC with Mysql: using mulitple outer joins with where clauses

I'm having an issue with the following query. It works in mysql workbench but not when I use it in java with jdbc. I keep getting a syntax error.
Here is the query:
"SELECT f.ISBN, f.text, m.title, AVG(r.rating) as score" +
" FROM RATES r LEFT OUTER JOIN FEEDBACK f ON (f.fid = r.fid) WHERE f.ISBN = ? " +
"LEFT OUTER JOIN MOVIE m ON (m.ISBN = f.ISBN) " +
"GROUP BY ISBN " +
"ORDER BY score DESC LIMIT ? ";
I did some searching and found a jdbc escape syntax of {oj }. But I would get another syntax error.
The error I am getting lately is:
HTTP Status 500 - javax.servlet.ServletException:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'LEFT OUTER JOIN
MOVIE m ON (m.ISBN = f.ISBN) GROUP BY ISBN ORDER BY score DESC L' at
line 1
I would love some fresh eyes on this since I can't seem to see my issue.
Thanks in advance!
I think that WHERE clause has to be placed behind JOINING. And next problem is that number of columns in select clause has equal to number of columns in group clause(except functions as avg, count etc.). So you need to correct your query like this:
SELECT f.ISBN, f.text, m.title, AVG(r.rating) as score
FROM RATES r
LEFT OUTER JOIN FEEDBACK f ON (f.fid = r.fid)
LEFT OUTER JOIN MOVIE m ON (m.ISBN = f.ISBN)
WHERE f.ISBN = ?
GROUP BY f.ISBN, f.text, m.title
ORDER BY score DESC LIMIT ?
The left join must be before the where clause. And every column listed in the select clause should be in the group by clause:
SELECT f.ISBN, f.text, m.title, AVG(r.rating) as score
FROM RATES r
LEFT OUTER JOIN FEEDBACK f ON (f.fid = r.fid)
LEFT OUTER JOIN MOVIE m ON (m.ISBN = f.ISBN)
WHERE f.ISBN = ?
GROUP BY f.ISBN f.text, m.title
ORDER BY score DESC
LIMIT ?

Distinct Popular Hits

Can someone help me with this query:
SELECT su.name,su.imdb , su.id, su.owner, COUNT(*) AS count
FROM subhits AS h LEFT JOIN subtitles AS su ON h.subid=su.id
WHERE su.added BETWEEN '" . $lweek . "' AND '" . $today . "'
GROUP BY h.subid
ORDER BY count DESC LIMIT 15
RETURNS:
name imdb id owner count
*Angels and Demons WTV /title/tt0808151/ 3337 3055 120
Terminator Salvation 2009 /title/tt0438488/ 3539 26 120
Friday The 13th-WTV /title/tt0758746/ 3334 26 82
Night at the Museum /title/tt1078912/ 3548 7170 75
*Angels and Demons WTV2 /title/tt0808151/ 3512 12 10
*DUPLICATED IMDB
As you see it returns results with the same imdb.
What i would like to do is get the highest count, but exclude the lowest imdb count from the result.
What I like about MySQL compared to Oracle, is how other fields not part of GROUP BY can be selected without using grouping functions. What the query below does is take your query and groups it by imdb, which selects a unique imdb with the highest count (which would appear first in the descending sort in the subselect). Try it and see if it works for you.
SELECT name, imdb, id, owner, count
FROM
(
SELECT su.name,su.imdb , su.id, su.owner, COUNT(*) AS count
FROM subhits AS h LEFT JOIN subtitles AS su ON h.subid=su.id
WHERE su.added BETWEEN '" . $lweek . "' AND '" . $today . "'
GROUP BY h.subid
ORDER BY count DESC
)
GROUP BY imdb
LIMIT 15
This may help.
http://www.artfulsoftware.com/infotree/queries.php?&bw=1280#101
I hate to say this, but this is one of those rare occasions where a temp table might help. If you put the results of this:
select
imdb,
id,
count(*) as cnt
from subtitles
group by
imdb,
id
..into a temp table, you can then get the rows you really want:
select
t.imdb,
t.id,
t.cnt
from MyTempTable t
inner join
(
select
imdb,
max(cnt) as maxcnt
from MyTempTable
group by
imdb
) as drv on t.imdb = drv.imdb and t.cnt = drv.maxcnt
..and the results of the above can be joined back into your main table without having to be grouped again.
Does this help?
Apologies for not putting all the SQL in but I'm pressed for time. This will do what you want but will still duplicate if the counts are the same. The query could be modified to deal with this if you care about it.
On a separate note, I'm not sure why you are left joining in the statement when you are not showing any data from the left hand table?
Try this:
SELECT su.name
, su.imdb
, su.id
, su.owner
, (SELECT COUNT(*) FROM dbo.subhits AS h WHERE h.subid = su.id) AS count
FROM dbo.subtitles AS su
ORDER BY count DESC LIMIT 15
Edit: Using the additional information provided I had an almost working solution but got stuck. Combining Chris Simpson's answer with the partial solution I came up with this. It avoids temp tables and has the missing pieces that the other Chris didn't have time to complete. I'm building this in MSSQL so it might need tweaking to work in MySQL. I also can't guarantee the information will be correct without your data but this might help.
SELECT a.id
, (SELECT su.name FROM dbo.subtitles su WHERE a.id = su.id LIMIT 1)
, a.imdb
, (SELECT su.owner FROM dbo.subtitles su WHERE a.id = su.id LIMIT 1)
, a.count
FROM
(
SELECT su.id
, su.imdb
, COUNT(*) AS count
FROM dbo.subtitles su
INNER JOIN dbo.subhits sh ON su.id = sh.subid
GROUP BY su.id, su.imdb
) a
INNER JOIN
(
SELECT c.imdb
, MAX(c.count) AS maxCount
FROM
(
SELECT su.id
, su.imdb
, COUNT(*) AS count
FROM dbo.subtitles su
INNER JOIN dbo.subhits sh ON su.id = sh.subid
GROUP BY su.id, su.imdb
) c
GROUP BY c.imdb
) b ON a.imdb = b.imdb AND a.count = b.maxCount
ORDER BY a.count DESC LIMIT 15
I'd try to test this myself, but I don't have your data or a good sample to test against.
SELECT su.name,su.imdb , su.id, su.owner, COUNT(*) AS counter
FROM subhits AS h LEFT JOIN subtitles AS su ON h.subid=su.id
WHERE su.added BETWEEN '" . $lweek . "' AND '" . $today . "'
GROUP BY h.subid
having max(counter)
ORDER BY count DESC LIMIT 15