MySQL syntax errors of equi join - mysql

i want to solve these two problems with equi join
For each customer order, list the order id, order date, order_source_id, source description, and the first and last name of the customer.
For each line in shipment_line, display the shipment_id, inv_id, ship_quantity, date_expected and date_received.
This is my syntax but it is showing error.
1.
SELECT order_id,order_date,order_source_id,source_desc,first,last
FROM customer,cust_order,order_source
WHERE (cust_order.order_source_id = order_source.order_source_id)
AND cust_order.cust_id = customer.cust_id;
2.
SELECT shipment_line.shipment_id,shipment_line.inv_id,shipment_line.date_recieved,shipment.date_expected
FROM shipment_line, shipment
WHERE shipment_line.shipment_id = shipment.shipment_id;

You could have ambiguous columns so you should add the related table name for each column:
SELECT cust_order.order_id
, cust_order.order_date
, cust_order.order_source_id
, order_source.source_desc
, customer.first
, customer.last
FROM customer
INNER JOIN cust_order ON cust_order.cust_id = customer.cust_id
INNER JOIN order_source ON cust_order.order_source_id = order_source.order_source_id
And you should not use old (pre 1992) implicit join syntax based on where clause but use explicit join class.
(Same problem for the second query).

Related

Mysql - I have 3 unique tables, need a hint on getting the details with the count

I have 3 tables which are interconnected and i want to select columns from two tables and counts from table 3. If anyone is aware on this, any hint would be appreciated.
Below is the sql i tried, but the count is getting repeated
SELECT distinct p.p_id, p.p_f6, p.p_l4,m.m_id, (
SELECT COUNT(*)
FROM ttokens t where t.pdetail_id = p.pdetail_id
) AS token_count
FROM tparking p,ttokens t LEFT join ttokens_md m ON t.trefn_id = m.trefn_id
WHERE t.pdetail_id = p.pdetail_id
You can try to use JOIN with subquery to get your count instead of selcet subquery.
SELECT p.p_id, p.p_f6, p.p_l4,m.m_id,t.cnt
FROM tparking p
JOIN (
SELECT pdetail_id,COUNT(*) cnt
FROM ttokens
GROUP BY pdetail_id
) t ON t.pdetail_id = p.pdetail_id
LEFT join ttokens_md m ON t.trefn_id = m.trefn_id
Note
I would use JOIN instead of , comma with where condition to connect two tables,, is an old style.

MySQL Inner join naming error?

http://sqlfiddle.com/#!9/e6effb/1
I'm trying to get a top 10 by revenue per brand for France on december.
There are 2 tables (first table has date, second table has brand and I'm trying to join them)
I get this error "FUNCTION db_9_d870e5.SUM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual"
Is my use of Inner join there correct?
It's because you had an extra space after SUM. Please change it from
SUM (o1.total_net_revenue)to SUM(o1.total_net_revenue).
See more about it here.
Also after correcting it, your query still had more error as you were not selecting order_id on your intermediate table i2 so edited here as :
SELECT o1.order_id, o1.country, i2.brand,
SUM(o1.total_net_revenue)
FROM orders o1
INNER JOIN (
SELECT i1.brand, SUM(i1.net_revenue) AS total_net_revenue,order_id
FROM ordered_items i1
WHERE i1.country = 'France'
GROUP BY i1.brand
) i2
ON o1.order_id = i2.order_id AND o1.total_net_revenue = i2.total_net_revenue
AND o1.total_net_revenue = i2.total_net_revenue
WHERE o1.country = 'France' AND o1.created_at BETWEEN '2016-12-01' AND '2016-12-31'
GROUP BY 1,2,3
ORDER BY 4
LIMIT 10`
--EDIT stack Fan is correct that the o2.total_net_revenue exists. My confusion was because the data structure duplicated three columns between the tables, including one that was being looked for.
There were a couple errors with your SQL statement:
1. You were referencing an invalid column in your outer-select-SUM function. I believe you're actually after i2.total_net_revenue.
The table structure is terrible, the "important" columns (country, revenue, order_id) are duplicated between the two tables. I would also expect the revenue columns to share the same name, if they always have the same values in them. In the example, there's no difference between i1.net_revenue and o1.total_net_revenue.
In your inner join, you didn't reference i1.order_id, which meant that your "on" clause couldn't execute correctly.
PROTIP:
When you run into an issue like this, take all the complicated bits out of your query and get the base query working correctly first. THEN add your functions.
PROTIP:
In your GROUP BY clause, reference the actual columns, NOT the column numbers. It makes your query more robust.
This is the query I ended up with:
SELECT o1.order_id, o1.country, i2.brand,
SUM(i2.total_net_revenue) AS total_rev
FROM orders o1
INNER JOIN (
SELECT i1.order_id, i1.brand, SUM(i1.net_revenue) AS total_net_revenue
FROM ordered_items i1
WHERE i1.country = 'France'
GROUP BY i1.brand
) i2
ON o1.order_id = i2.order_id AND o1.total_net_revenue = i2.total_net_revenue
AND o1.total_net_revenue = i2.total_net_revenue
WHERE o1.country = 'France' AND o1.created_at BETWEEN '2016-12-01' AND '2016-12-31'
GROUP BY o1.order_id, o1.country, i2.brand
ORDER BY total_rev
LIMIT 10

MySQL table Join for Multiple Values

I have 2 tables, one with 2 columns of product ids (old and new) that need to mapped to each other and another table with all the product info, including a corresponding product id. I am trying to run a query to double check that the products are matched correctly and it is not working, I need the returned results to show the old id and newid along with the full product info.
Here is what I cobbled together from some other queries I use, but I am not sure I am doing the double join correctly.
SELECT `VinylOld2New`.`Old ID`, `asi_VinylOld2New`.`New ID`, old.`title`, new.`title`, old.`number`, new.`number`, old.`image`, new.`image`, old.`added`, new.`added`
FROM `ii_Product` old, `ii_Product` new
INNER JOIN `VinylOld2New` ON
old.`id` = `VinylOld2New`.`Old ID` OR new.`id` = `VinylOld2New`.`New ID`
Pick a standard. Use INNER JOIN or , notation both both. (preferably the newer standard)
I'm not sure how you want to join the data here. Your use of OR seems to imply you want all records from vinylOld2New and only those that match in ii_product (old or new) but that's a guess.
Your 2nd column in select indicates asi_VinylOld2New.New ID but there is no such table. So is the table in the select wrong or the one in the from?
.
SELECT `VinylOld2New`.`Old ID`
, `VinylOld2New`.`New ID`
, old.`title`
, new.`title`
, old.`number`
, new.`number`
, old.`image`
, new.`image`
, old.`added`
, new.`added`
FROM `VinylOld2New`
LEFT JOIN `ii_Product` old
ON old.`id` = `VinylOld2New`.`Old ID`
LEFT JOIN `ii_Product` new
ON new.`id` = `VinylOld2New`.`New ID`

LEFT OUTER JOIN selects just one row

I am trying to SELECT data from my database with the method LEFT OUTER JOIN but when I run my syntax the result is just one row. I am sure the result must be more rows.
I also tried the method FULL OUTER JOIN instead of LEFT OUTER JOIN. But when I do that I get an syntax error.
Does someone know why I am gettin just one row?
Here is my sql syntax:
SELECT
cus.cus_id
, cus.name_cus
, cus.address, count(invoice.id) as id2
, CONCAT('€ ', ROUND(SUM(invoice.total),2)) as total
, cus.id
FROM cus
LEFT OUTER JOIN invoice
ON cus.cus_id = invoice.cus_id
You are using aggregate functions without GROUP BY clause:
SELECT
cus.cus_id
, cus.name_cus
, cus.address
, count(invoice.id) as id2
, CONCAT('€ ', ROUND(SUM(invoice.total),2)) as total
, cus.id
FROM cus
LEFT OUTER JOIN invoice ON cus.cus_id = invoice.cus_id
GROUP BY cus.cus_id, cus.name_cus, cus.address, cus.id
Although you need to group only by the unique ID (i.e. cus.id) you should add other fields that are not aggregated to GROUP BY clause as well, even though they do not create additional groups.

MySQL Inner Join with where clause sorting and limit, subquery?

Everything in the following query results in one line for each invBlueprintTypes row with the correct information. But I'm trying to add something to it. See below the codeblock.
Select
blueprintType.typeID,
blueprintType.typeName Blueprint,
productType.typeID,
productType.typeName Item,
productType.portionSize,
blueprintType.basePrice * 0.9 As bpoPrice,
productGroup.groupName ItemGroup,
productCategory.categoryName ItemCategory,
blueprints.productionTime,
blueprints.techLevel,
blueprints.researchProductivityTime,
blueprints.researchMaterialTime,
blueprints.researchCopyTime,
blueprints.researchTechTime,
blueprints.productivityModifier,
blueprints.materialModifier,
blueprints.wasteFactor,
blueprints.maxProductionLimit,
blueprints.blueprintTypeID
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
So what I need to get in here is the following table with the columns below it so I can use the values timestamp and sort the entire result by profitHour
tablename: invBlueprintTypesPrices
columns: blueprintTypeID, timestamp, profitHour
I need this information with the following select in mind. Using a select to show my intention of the JOIN/in-query select or whatever that can do this.
SELECT * FROM invBlueprintTypesPrices
WHERE blueprintTypeID = blueprintType.typeID
ORDER BY timestamp DESC LIMIT 1
And I need the main row from table invBlueprintTypes to still show even if there is no result from the invBlueprintTypesPrices. The LIMIT 1 is because I want the newest row possible, but deleting the older data is not a option since history is needed.
If I've understood correctly I think I need a subquery select, but how to do that? I've tired adding the exact query that is above with a AS blueprintPrices after the query's closing ), but did not work with a error with the
WHERE blueprintTypeID = blueprintType.typeID
part being the focus of the error. I have no idea why. Anyone who can solve this?
You'll need to use a LEFT JOIN to check for NULL values in invBlueprintTypesPrices. To mimic the LIMIT 1 per TypeId, you can use the MAX() or to truly make sure you only return a single record, use a row number -- this depends on whether you can have multiple max time stamps for each type id. Assuming not, then this should be close:
Select
...
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Left Join (
SELECT MAX(TimeStamp) MaxTime, TypeId
FROM invBlueprintTypesPrices
GROUP BY TypeId
) blueprintTypePrice On blueprints.blueprintTypeID = blueprintTypePrice.typeID
Left Join invBlueprintTypesPrices blueprintTypePrices On
blueprintTypePrice.TypeId = blueprintTypePrices.TypeId AND
blueprintTypePrice.MaxTime = blueprintTypePrices.TimeStamp
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
Order By
blueprintTypePrices.profitHour
Assuming you might have the same max time stamp with 2 different records, replace the 2 left joins above with something similar to this getting the row number:
Left Join (
SELECT #rn:=IF(#prevTypeId=TypeId,#rn+1,1) rn,
TimeStamp,
TypeId,
profitHour,
#prevTypeId:=TypeId
FROM (SELECT *
FROM invBlueprintTypesPrices
ORDER BY TypeId, TimeStamp DESC) t
JOIN (SELECT #rn:=0) t2
) blueprintTypePrices On blueprints.blueprintTypeID = blueprintTypePrices.typeID AND blueprintTypePrices.rn=1
You don't say where you are putting the subquery. If in the select clause, then you have a problem because you are returning more than one value.
You can't put this into the from clause directly, because you have a correlated subquery (not allowed).
Instead, you can put it in like this:
from . . .
(select *
from invBLueprintTypesPrices ibptp
where ibtp.timestamp = (select ibptp2.timestamp
from invBLueprintTypesPrices ibptp2
where ibptp.blueprintTypeId = ibptp2.blueprintTypeId
order by timestamp desc
limit 1
)
) ibptp
on ibptp.blueprintTypeId = blueprintType.TypeID
This identifies the most recent records for all the blueprintTypeids in the subquery. It then joins in the one that matches.