Get average number from SQL statement - mysql

I've got a SQL statement:
SELECT AVG(`totalhours`)/5 AS `average`,* FROM `report_signout` JOIN `employee` ON `employee`.`username`=`report_signout`.`username`
However it's not working. Basically I need to calculate the average total hours an employee has been on the premises in any one week, the assumption is accepted that the office is only open 5 days a week. The total hours are coming from the table report_signout which I need to join on the username of the employee table so I can produce an outcome where I can then list the Firstname and Lastname of the employee along with the average hours on a web page. That last part is done in PHP which I already know how to do. I just need to see where I'm going wrong with the SQL statement.
If someone could point out to me please or give me a bit of help it would be much appreciated, thanks!

MySQL does not really know what totalhours is. As you are referencing more than one table, a table is not assumed, so you need to declare what to average by defining the reference as:
`table name`.`column name`
This is true for most if not all MySQL built in functions. Use absolute declarations (ie those with table and column names both defined, as above) as much as possible.
SELECT AVG(`report_signout`.`totalhours`)/5 AS `average`,
`report_signout`.*, `employee`.*
FROM `report_signout`
INNER JOIN `employee` ON `employee`.`username` = `report_signout`.`username`
As a small aside, try and avoid vague JOIN referencing instead using a complete JOIN reference, which states the type of JOIN rather than an assumption.
Also try to avoiding using * selection instead stating each column you wish to call.

Related

MYSQL - Syntax for Joining My 3 Tables Correctly

Edit2: Chose to separate the queries and collate/handle the information as a whole outside of the database's output. Taking these out in a .CSV format, and adding them into Excel where I'm going to be running the actual numbers.
Query 1 to pull out orders and desired info:
SELECT
shipstation_orders_v2.id AS SSO_id,
shipstation_orders_v2.order_number AS SSO_orderNumber,
shipstation_orders_v2.order_id AS SSO_orderID,
shipstation_orders_v2.storename AS SSO_storeName,
shipstation_orders_v2.order_date AS SSO_orderDate,
shipstation_orders_v2.order_total AS SSO_orderTotal,
shipstation_orders_v2.name AS SSO_name,
shipstation_orders_v2.company AS SSO_company
FROM shipstation_orders_v2
GROUP BY shipstation_orders_v2.id,
shipstation_orders_v2.order_number,
shipstation_orders_v2.order_id,
shipstation_orders_v2.storename,
shipstation_orders_v2.order_date,
shipstation_orders_v2.order_total,
shipstation_orders_v2.name,
shipstation_orders_v2.company
ORDER BY SSO_orderDate
Query 2 to pull out fulfillments and equivalent info:
SELECT DISTINCT
shipstation_orders_v2.id AS SSO_id,
shipstation_fulfillments.id AS SSF_id,
shipstation_fulfillments.order_number AS SSF_orderNumber,
shipstation_orders_v2.order_number AS SSO_orderNumber,
shipstation_orders_v2.order_id AS SSO_orderID,
shipstation_orders_v2.storename AS SSO_storeName,
shipstation_orders_v2.order_date AS SSO_orderDate,
shipstation_fulfillments.order_date AS SSF_orderDate,
shipstation_orders_v2.order_total AS SSO_orderTotal,
shipstation_fulfillments.amount_paid AS SSF_amountPaid,
shipstation_orders_v2.name AS SSO_name,
shipstation_orders_v2.company AS SSO_company,
shipstation_fulfillments.name AS SSF_name,
shipstation_fulfillments.company AS SSF_company
FROM shipstation_fulfillments
INNER JOIN shipstation_orders_v2
ON shipstation_fulfillments.order_number =
shipstation_orders_v2.order_number
WHERE shipstation_fulfillments.order_number =
shipstation_orders_v2.order_number
GROUP BY shipstation_orders_v2.id,
shipstation_fulfillments.id,
shipstation_fulfillments.order_number,
shipstation_orders_v2.order_number,
shipstation_orders_v2.order_id,
shipstation_orders_v2.storename,
shipstation_orders_v2.order_date,
shipstation_fulfillments.order_date,
shipstation_orders_v2.order_total,
shipstation_fulfillments.amount_paid,
shipstation_orders_v2.name,
shipstation_orders_v2.company,
shipstation_fulfillments.name,
shipstation_fulfillments.company
Edit: Question marked as answered. I figured out another way to do it that wasn't quite as harebrained. Props to DRapp for getting my brain moving.
Original Code is below Wall of Text
I'm a self-taught MySQL database user. I won't say administrator, since it's just me. I've put together a small database for work - about 60,000 rows and a maximum of 51 columns spread over three tables. I use this at work as a way to organize a fairly disparate sales data setup and make sense of it to identify trends, seasonality, all that good stuff. I work primarily with Shipstation data.
My problem is when I needed to introduce this third table. With two tables, obviously, it's just a simple JOIN. I got that working just fine. I'm having quite a bit of trouble setting up the JOINs correctly for this third table.
I'm attempting to JOIN the data from the two innermost queries to shipstation_orders_v2 and order_keys to the shipstation_fulfillments results I have in the third table.
For those of you who don't use Shipstation or aren't familiar with this element of it, fulfillments are in a different category than orders and don't use quite the same data. This is my dirty way of gluing them together so we have some decent, manipulable information on sales and shipping trends, etc.
I am making an internal query from shipstation_orders_v2 to order_keys as a way to SELECT DISTINCT the sum totals of split orders. I had problems with data duplication before I built up that subquery. With the (now) subquery and sub-subquery, the duping problem has been eliminated and with just those two tables it worked fine.
The issue is, when I'm making the SELECT from shipstation_fulfillments with a JOIN to the subquery and sub-subquery, I'm hitting a roadblock.
I've gotten several errors while working on this query. In order of occurrence and resolution:
Error 2013, lost connection to server during query (which told me I'm doing a full table read on three joined tables, since it isn't erroring out beforehand, but my rinkadink setup can't handle it). I got rid of that one.
Then, Error 1051 for an unidentified table name shipstation_fulfillments. To me I think it might be an issue for the query aliases. I am not sure.
Finally, good ole Error 1064, incorrect syntax on the first subquery after the
SELECT shipstation_fulfillments arguments.
Being self-taught, I'd virtually guarantee I'm merely missing an element of syntax somewhere that would appear fairly obvious to a well-practiced user of MySQL. Below is my current query setup.
If there needs to be any clarification, let me know.
SELECT
`shipstation_fulfillments`.`order_date` AS `orderDate`,
`shipstation_fulfillments`.`order_number` AS `orderNumber`,
(`shipstation_fulfillments`.`amount_paid` + `shipstation_fulfillments`.`tax_paid`) AS "Total Paid",
`shipstation_fulfillments`.`name` AS `name`,
`shipstation_fulfillments`.`company` AS `company`,
FROM
(
(SELECT
COUNT(`shipstation_orders_v2`.`order_key`) AS `orderCount`,
`shipstation_orders_v2`.`key_id` AS `key_id`,
`shipstation_orders_v2`.`order_number` AS `order_number`,
MAX(`shipstation_orders_v2`.`order_date`) AS `order_date`,
`shipstation_orders_v2`.`storename` AS `store`,
(`shipstation_orders_v2`.`order_total` - `shipstation_orders_v2`.`shippingPaid`) AS `orderPrice`,
`shipstation_orders_v2`.`shippingpaid` AS `shippingPaid`,
SUM(`shipstation_orders_v2`.`shippingpaid`) AS `SUM shippingPaid`,
`shipstation_orders_v2`.`order_total` AS `orderTotal`,
SUM(`shipstation_orders_v2`.`order_total`) AS `SUM Total Amount Paid`,
`shipstation_orders_v2`.`qtyshipped` AS `qtyShipped`,
SUM(`shipstation_orders_v2`.`qtyshipped`) AS `SUM qtyShipped`,
`shipstation_orders_v2`.`name` AS `name`,
`shipstation_orders_v2`.`company` AS `company`
FROM
(SELECT DISTINCT
`order_keys`.`key_id` AS `key_id`,
`order_keys`.`order_key` AS `order_key`,
`shipstation_orders_v2`.`order_number` AS `order_number`,
`shipstation_orders_v2`.`order_id` AS `order_id`,
`shipstation_orders_v2`.`order_date` AS `order_date`,
`shipstation_orders_v2`.`storename` AS `storename`,
`shipstation_orders_v2`.`order_total` AS `order_total`,
`shipstation_orders_v2`.`qtyshipped` AS `qtyshipped`,
`shipstation_orders_v2`.`shippingpaid` AS `shippingpaid`,
`shipstation_orders_v2`.`name` AS `name`,
`shipstation_orders_v2`.`company` AS `company`
FROM
(`shipstation_orders_v2`
JOIN `order_keys` ON ((`order_keys`.`order_key` = `shipstation_orders_v2`.`order_id`)))) `t`)
JOIN `shipstation_fulfillments`
ON (`shipstation_orders_v2`.`order_number` = `shipstation_fulfillments`.`order_number`)) `w`
As a couple notes... As for long table names, no problem, but you can use alias references to them such as I have done via example ...ShipStation_Fulfillments SSF... the "SSF" is now an alias for shorter typing yet still makes sense of origin.
When changing column names in query via "AS", you only need the as if your column name result will change from its original as you had in the beginning such as SSF.order_date AS orderDate where you remove the "_" from the final column name, but also in "Total Paid" (yet I HATE column names with embedded spaces, let the user interface handle labeling things, but thats just me).
When typing table.column (or alias.column), doing via CamelCasing helps readability vs camelcasing slightly harder to read where the brain naturally breaks into readable words for us.
Other issue based on query. Outer query portions can't recognize aliases from inner closed queryies, only the alias of the subselect as you had with the "t" and "w" aliases.
Next, when doing JOINs, my preference is to read them in the way the tables are within the query listing the first one on the left, and whatever is joined TO on the right.
If went from Table A Join to Table B, the ON clause would be ON A.KeyID = B.KeyID vs B.KeyID = A.KeyID especially if you are going several tables... A->B, B->C, C->D
Any query with aggregates (sum, avg, count, min, max, etc) must have a "GROUP BY" clause to identify when each record should break. In your example, I would assume break on the original sales order.
Although this query IS NOT WORKING, here is a cleaned-up version of your query showing implementations from above.
SELECT
SSF.order_date AS OrderDate,
SSF.order_number AS OrderNumber,
(SSF.amount_paid + SSF.tax_paid) AS `Total Paid`,
SSF.name,
SSF.company
FROM
( SELECT
SSOv2.key_id,
SSOv2.order_number,
SSOv2.storename AS store,
SSOv2.order_total - SSOv2.shippingPaid AS OrderPrice,
SSOv2.ShippingPaid,
SSOv2.order_total AS OrderTotal,
SSOv2.QtyShipped,
SSOv2.name,
SSOv2.company,
COUNT(SSOv2.order_key) AS orderCount,
MAX(SSOv2.order_date) AS order_date,
SUM(SSOv2.shippingpaid) AS `SUM shippingPaid`,
SUM(SSOv2.order_total) AS `SUM Total Amount Paid`,
SUM(SSOv2.qtyshipped) AS `SUM qtyShipped`
FROM
( SELECT DISTINCT
OK.key_id AS key_id,
OK.order_key AS order_key,
SSOv2.order_number AS order_number,
SSOv2.order_id AS order_id,
SSOv2.order_date AS order_date,
SSOv2.storename AS storename,
SSOv2.order_total AS order_total,
SSOv2.qtyshipped AS qtyshipped,
SSOv2.shippingpaid AS shippingpaid,
SSOv2.name AS name,
SSOv2.company AS company
FROM
shipstation_orders_v2 SSOv2
JOIN order_keys
ON SSOv2.order_id = OK.order_key
JOIN shipstation_fulfillments SSF
ON SSOv2.order_number = SSF.order_number ) t
) w
Next, without seeing actual data or listed structures critical to solve the query, I will ask you edit your existing post. Create a sample table listing table, columns and sample data so we can see the basis of what you are aggregating and trying to get out of the query. Especially show where there could be multiple rows per order and fulfillment respectively and a sample answer of what you EXPECT the results to show.

Join two SQL Queries based on first query answer

I have been looking everywhere and this would be the best website to ask someone for the help. I have to make SQL query that checks the total amount of bookings for the specific flight and then based on the number of bookings the system should provide the choice of an aircraft. First query works and it finds total number of bookings and i think i have the case statement right to choose an aircraft but i cant find the way of physically joining both queries , i tried to use unison , inner join and nested queries but it appears that Total number of seats booked (the answer from first query ) cannot be found please help me guys.
First SQL Query(find total number of bookings )
SELECT count(bookingdetails.FlightID)AS TotalNumberOfSeatsBooked,flightdetails.FlightID
FROM bookingdetails, bookingdetails AS TEMP,flightdetails
WHERE bookingdetails.BookingID = TEMP.BookingID
AND bookingdetails.FlightID= flightdetails.FlightID
Group BY FlightID;
SECOND SQL Query(Choose an aircraft type depending on how many bookings are made)
SELECT CASE chooseaircraft
WHEN TotalNumberOfSeatsBooked <= 110 THEN 'BA 146-200'
ELSE'Embraer 170'
END AS ChoiceOfAircraft
FROM aircrafttype;
Big Thanks to everyone
After one answer i think im heading in the right direction with merging the both queries together , the code now displays the total number of seats and flight number in the sub query but the choice of aircraft column still doesnt show but it does if you run the query by it self i know i am close to getting this and i would appreciate any help to become better in SQL the code i have now is :
SELECT count(bookingdetails.FlightID)AS TotalNumberOfSeatsBooked,flightdetails.FlightID
FROM bookingdetails, bookingdetails AS TEMP,flightdetails
WHERE bookingdetails.BookingID = TEMP.BookingID
AND bookingdetails.FlightID= flightdetails.FlightID
AND bookingdetails.FlightID= flightdetails.FlightID IN(
SELECT CASE WHEN count(bookingdetails.FlightID) <= 110 THEN 'BA 146-200'
ELSE'Embraer 170'
END AS ChoiceOfAircraft
FROM bookingdetails,flightdetails)
Group BY FlightID;
You can use the same expression count(bookingdetails.FlightID) in your CASE statement (or) wrap your first query in a subquery and access the column in your outer query. That is
CASE WHEN count(bookingdetails.FlightID) <= 110 THEN 'BA 146-200'
ELSE'Embraer 170'
END AS ChoiceOfAircraft

SQL Outer Join Time Series with Data in Different Times

I was trying to combine multiple Cash Flows table for multiple projects into one table using SQL. The query i was using is listed below,
SELECT a.DATE1, b.DATE2, a.CF1, b.CF2
FROM a
FULL OUTER JOIN b
ON b.DATE2= a.DATE1
and the result table is listed below,
Since cash flows are taken place in different date for different project, some of them might happen in same day, some might not. I am wondering how can I adjust my code so that the result will looks like this,
Where we combine first 2 date columns. Keep the date value if the other one is NULL, and remove duplicated values if cash flows happened on the same day.
Since there are multiple projects I will need to combine, the method should be robust for expansion.
I have tried to use following,
SELECT ISNULL(a.DATE1, '') + ISNULL(b.DATE2, ''), a.CF1, b.CF2
FROM ...
However, this only solves the NULL part, and will actually add up duplicated date, and result in a new date.
Any help is appreciated, and thanks a lot in advance!
Try This using coalesce().
SELECT coalesce(a.DATE1, b.DATE2)as date, a.CF1, b.CF2
FROM a
FULL OUTER JOIN b
ON b.DATE2= a.DATE1

Not sure where I went wrong on a sql join

The most programming I do is shell scripts or some python or perl, so I have a basic understanding after Googling for a bit. A little background on what i’m doing. We have two inventory systems: Our’s and Their’s. I need to pull information from Their’s to compare with Our’s.
The problem: We need UPC’s to do inventory while They provide SKU’s in their monthly inventory report.
The solution: Join 3 tables. I’m using phpmyadmin to manage a mysql backend on a recent install of Debain Wheezy.
The first query takes every SKU They have in Their inventory, compares it with the UPC in Their listings and, since not every ‘UPC’ is actually a UPC, compares it to the UPC in Our listings. It looks like this:
SELECT TheirListings.upc, SUM(TheirInventory.quantity)
FROM TheirInventory
JOIN TheirListings
ON TheirListings.sku = TheirInventory.sku
JOIN OurListings
ON TheirListings.upc = OurListings.Upc
GROUP BY TheirListings.upc
ORDER BY TheirListings.upc
And it seems to work well. Our system is happy with it and it makes me happy because this reduces manual entry by 96%. Now I need to get everything this didn’t catch: the 4% that does need manual entry. Our tables shortened for brevity like this:
TheirListings TheirInventory OurListings
upc sku upc
sku quantity
I need to select all the SKU’s and associated quantities:
SELECT TheirInventory.sku, SUM(TheirInventory.quantity)
FROM TheirInventory
LEFT OUTER JOIN TheirListings
ON TheirListings.sku = TheirInventory.sku
LEFT OUTER JOIN OurListings
ON TheirListings.upc = OurListings.upc
WHERE OurListings.upc IS NULL
OR TheirListings.upc IS NULL
GROUP BY TheirInventory.sku
ORDER BY TheirInventory.sku
To double check it’s catching the remainder, I did SELECT COUNT(TheirInventory.sku) for both of those queries and another to return the total of sku’s. Adding my two queries gives me exactly 1 more than expected. I’m not sure where I went wrong.
The first thing I would guess is that they're not working on the same datasets. If you ran the first one a few days ago, perhaps some data has changed causing it to show up in the second query?
If not, what I would do is
SELECT SKU
FROM TheirInventory
WHERE SKU IN (<1st query>)
AND SKU IN (<2nd query>)
This will tell you what is showing up in both, and you can diagnose from there.

MYSQL Query fails on Left join

I am in fight with an sql query i cant seem to figure out, and hope somebody might help me with this.
I got two tables i want to have connected together. My first table is the 'achievement' table, which has 3 fields: achievementId, AchievementName and ZoneId
My second table is a table that is in between my User and this achivement table, which stores basically also 3 items. The UserId, AchievementId and IsChecked. It refers here to a checkbox.
So I am working on a page that shows all the achievements in the form of a checkbox list, so I want to have those who are already achieved to be shown in the list, however, the query i am trying to get fails completely and I have no idea how to fix it. I tried the below item, but off course I failed miserable. So I was hoping if you guys could help me out here and adjust my query.
My current query is
Select * from Achievement
Where Zone = '2'
LEFT JOIN Achievement_User
Where Achievement_User.UserId='2'
And Achievement_User.AchievementId = Achievement.AchievementId
but it fails off course. I probably have the syntax wrong, but I cant figure it out. If somebody could help me out?
EDIT I think i explained this wrong. But the left join shows only the ones that match, however, I need the full list of the achievement, which is like 40 rows, it only shows now the rows where there is data from the Achievement_User with the query supplied by #Aquillo. I prefer ot have all 40 rows supplied by the Achivements with zone 2
First you have two WHERE-clauses, secondly a JOIN is a JOIN ON. Try this:
Select *
from Achievement
LEFT JOIN Achievement_User ON Achievement_User.AchievementId = Achievement.AchievementId
Where Zone = '2'
Update in response to OP's update
In that case you shouldn't use a restriction on the UserID, try the above query.