Unknown Column error executing left join - mysql

I am trying to get a left join to work and have an error that says
Unknown column 'sales_order_grid.entity_id' in 'on clause
However I don't know how to re-word the query the column sales_order_grid does contain a column named entity_id? I am trying to run a query that shows results even if the sales_order_tax table has no matching row I want the rest of the data from the other tables to show.
SELECT sales_order_grid.entity_id, sales_order_grid.created_at, sales_order_grid.increment_id AS OrderID, sales_order_grid.status, sales_order_grid.payment_method AS payment_method, sales_order_grid.base_grand_total AS pmt, sales_order_grid.base_grand_total AS charged, t.code AS tax_code, t.title AS taxrate, t.amount AS taxamount,
sales_order_grid.shipping_and_handling AS shipping_invoice, sales_order_grid.grand_total AS total_invoice, customer_address_entity.firstname, customer_address_entity.lastname,
customer_address_entity.city, customer_address_entity.region, customer_address_entity.postcode
FROM sales_order_grid, customer_address_entity LEFT OUTER JOIN sales_order_tax AS t on sales_order_grid.entity_id = t.order_id
WHERE sales_order_grid.created_at >= '2018-02-01 00:00:00'
AND sales_order_grid.created_at <= '2018-02-05 23:59:59'
AND sales_order_grid.status IN('Paid','complete','closed','Processing','on hold')
AND sales_order_grid.customer_id = customer_address_entity.parent_id
GROUP BY sales_order_grid.entity_id

You are mixing up 2 different ways in joining your tables.
Your query should look like this:
SELECT sales_order_grid.entity_id, sales_order_grid.created_at, sales_order_grid.increment_id AS OrderID, sales_order_grid.status, sales_order_grid.payment_method AS payment_method, sales_order_grid.base_grand_total AS pmt, sales_order_grid.base_grand_total AS charged, t.code AS tax_code, t.title AS taxrate, t.amount AS taxamount,
sales_order_grid.shipping_and_handling AS shipping_invoice, sales_order_grid.grand_total AS total_invoice, customer_address_entity.firstname, customer_address_entity.lastname,
customer_address_entity.city, customer_address_entity.region, customer_address_entity.postcode
FROM sales_order_grid
JOIN customer_address_entity on sales_order_grid.customer_id = customer_address_entity.parent_id
LEFT OUTER JOIN sales_order_tax AS t on sales_order_grid.entity_id = t.order_id
WHERE sales_order_grid.created_at >= '2018-02-01 00:00:00' AND sales_order_grid.created_at <= '2018-02-05 23:59:59'
AND sales_order_grid.status IN('Paid','complete','closed','Processing','on hold') GROUP BY sales_order_grid.entity_id

Related

MySQL aggregate select query returning incorrect data

I have the following code:
SELECT gl.account_description AS invoice_total, COUNT(ili.invoice_id) AS total_invoice,
SUM(ili.line_item_amount) AS total_convert
FROM general_ledger_accounts gl JOIN
invoice_line_items ili
ON gl.account_number = ili.account_number JOIN
invoices i
ON ili.invoice_id = i.invoice_id
GROUP BY gl.account_description, i.invoice_date, ili.account_number
HAVING i.invoice_date BETWEEN '2014-04-01' AND '2014-06-30' AND
COUNT(ili.account_number) > 1
ORDER BY account_description DESC;
In my query I am supposed to have 10 rows of data returned and I'm only having 7 return and none of them with the correct information. What I should have returning is the account_description column from the general_ledger_accounts table, a count of the items in the invoice_line_items table, a sum of the line_item_amount columns in the invoice_line_items table that have the same account number. It should only be searching within invoices between the dates '2014-04-01' and '2014-06-30'. I'm supposed to join in the invoices table.
Can anyone see what it is that I'm doing wrong in my syntax to get the wrong results?
Obviously, you want a WHERE clause and not a HAVING clause for filtering on the dates -- and to remove the date from the GROUP BY (you are not selecting it):
SELECT gl.account_description AS invoice_total,
COUNT(*) AS total_invoice,
SUM(ili.line_item_amount) AS total_convert
FROM general_ledger_accounts gl JOIN
invoice_line_items ili
ON gl.account_number = ili.account_number JOIN
invoices i
ON ili.invoice_id = i.invoice_id
WHERE i.invoice_date BETWEEN '2014-04-01' AND '2014-06-30'
GROUP BY gl.account_description, ili.account_number
HAVING COUNT(*) > 1
ORDER BY account_description DESC;
I don't know if there are other issues.
I suspect that you want to remove columns i.invoice_date and ili.account_number from the group by clause. Otherwise, you get one record per distinct values of these three columns, which does not seem to be what you want.
Accordingly, you should move the filter on the dates to the where clause:
SELECT
gl.account_description AS invoice_total,
COUNT(ili.invoice_id) AS total_invoice,
SUM(ili.line_item_amount) AS total_convert
FROM general_ledger_accounts gl
INNER JOIN invoice_line_items ili
ON gl.account_number = ili.account_number
INNER JOIN invoices i
ON ili.invoice_id = i.invoice_id
WHERE
i.invoice_date >= '2014-04-01'
AND i.invoice_date < '2014-07-01'
GROUP BY gl.account_description
HAVING COUNT(ili.account_number) > 1
ORDER BY g1.account_description DESC;
Note that I modified the condition on the dates to use half-open intervals: this way, you don't have to worry about whether the last month has 30 or 31 days (or 28, or 29...); this would also smoothly handle the time part of the dates, if any.

What's wrong with my SQL? (MySQL syntax error, code 1064)

I have
select created_at, sales_flat_order.customer_id,
customer_firstname, customer_lastname, customer_email,
sales_flat_order_address.company,
SUM(grand_total)
from sales_flat_order
left join sales_flat_order_address
on sales_flat_order.entity_id = sales_flat_order_address.entity_id
where created_at >= '2016-06-01 05:00:00' /* 5h difference */
and store_id = 1
and `status` = 'Complete'/*
left join customer_entity
on sales_flat_order.customer_id = customer_entity.entity_id*/
group by customer_email;
Runs fine. Comment content produces error with SQL syntax, code 1064. What's the problem?
Same issue now with this:
select customer.entity_id, customer.group_id,
customer.created_at,
sfo.customer_firstname, sfo.customer_lastname,
sfo.customer_email,
sfo.created_at last_order,
count(sfo.customer_id) num_orders,
group_concat(sfo.grand_total separator '|') grand_totals
from customer_entity customer
inner join sales_flat_order sfo
on customer.entity_id = sfo.customer_id
where sfo.created_at >= '2016-06-01 05:00:00'
and sfo.store_id = 1
and sfo.`status` = 'Complete'
left outer join customer_group
on customer.group_id = customer.customer_group_id
where customer_group.customer_group_id
group by customer.entity_id;
Thanks everyone, that all makes ample sense, definitely getting into the hang of it; how's this? It works but tear it up if anything remains amuck.
select customer.entity_id, customer.group_id, `group`.customer_group_code,
customer.created_at,
`order`.customer_firstname, `order`.customer_lastname,
`order`.customer_email, address.company,
`order`.created_at last_order,
count(`order`.customer_id) num_orders,
group_concat(`order`.grand_total separator '|') grand_totals
from customer_entity customer
inner join sales_flat_order `order`
on customer.entity_id = `order`.customer_id
left outer join customer_group `group`
on customer.group_id = `group`.customer_group_id
left outer join sales_flat_order_address address
on `order`.entity_id = address.entity_id
where `order`.created_at >= '2016-06-01 05:00:00'
and `order`.store_id = 1
and `order`.`status` = 'Complete'
group by customer.entity_id;
I know everyone said to add to the group by clause but there is nothing else I want to group by...?
The where clause must be after all of the joins. There are other issues as well, but that's the issue that really breaks things.
If it were me, I'd also fix the group by clause to match the select list, but MySql lets you write non-standard SQL in this way. You may also have a naming conflict when you add the additional table because you haven't qualified the column names. Aliases would make this easier to do Finally, it's possible for your query logic that you want some of the conditional expressions in the where clause to be part of the first ON clause.
If you format your code properly, it's easy to see why your code doesn't work. Your commented LEFT JOIN that caused the error is after the WHERE clause. Also write proper SQL. Alias your table name because long column names are annoying. Put all non-aggregated columns in the GROUP BY clause. Your code won't even run in any other dbms except for maybe MySQL.
select created_at, sales_flat_order.customer_id
, customer_firstname, customer_lastname
, customer_email
, sales_flat_order_address.company
, SUM(grand_total)
from sales_flat_order
left join sales_flat_order_address on sales_flat_order.entity_id = sales_flat_order_address.entity_id
where created_at >= '2016-06-01 05:00:00' /* 5h difference */
and store_id = 1
and `status` = 'Complete'/*
left join customer_entity on sales_flat_order.customer_id = customer_entity.entity_id*/
group by customer_email;

MySQL left join missing results

I'm trying to see if I have some unused SIP numbers, so I have a list of numbers in the table tmp_numbers
0203XXXXX00
0203XXXXX01
0203XXXXX02
0203XXXXX03
...
The query I use is:
SELECT
n.number,
COUNT(c.did) AS count
FROM tmp_numbers n
LEFT JOIN cdr c
ON n.number = c.did
WHERE c.calldate >= '2017-01-01'
GROUP BY n.number
ORDER BY n.number
I get results from the above query, but it omits numbers it can't match on c.did.
I was under the impression that a LEFT JOIN would match/display everything on left table (tmp_numbers), regardless if there is a value on the right side (so it will show NULL?)
What am I missing here?
Put the where condition in the left join. Otherwise it turns implicitly into an inner join because conditions in the where clause filter on all data and if calldate is NULL then the condition is FALSE
LEFT JOIN cdr c ON n.number = c.did
AND c.calldate >= '2017-01-01'
You are querying on a column from the JOINED table which maybe null if there is no corresponding entry, so change the WHERE condition from:
WHERE c.calldate >= '2017-01-01'
to
WHERE c.calldate >= '2017-01-01' OR c.did IS NULL

COUNT(*) does not count correctly

I'm having trouble with a mysql query.
SELECT switch_id, port_id, isp_service.service, isp_service.id
FROM traffic, isp_service
WHERE datetime>='2013-09-01 00:00:00'
AND datetime<'2013-09-02 00:00:00'
AND isp_service.id=traffic.isp_service_id
GROUP BY switch_id, port_id
This query returns me 1000 rows.
Now I am trying to count how many users each service has so I did:
SELECT ris.id, COUNT(*) as numberOfUsers
FROM
(SELECT switch_id, port_id, isp_service.service, isp_service.id
FROM traffic, isp_service
WHERE datetime>='2013-09-01 00:00:00'
AND datetime<'2013-09-02 00:00:00'
AND isp_service.id=traffic.isp_service_id
GROUP BY switch_id, port_id)ris
GROUP BY ris.id
ORDER BY ris.id
Now, how is possible that if I sum up the column numberOfUser the results is bigger than 1000?
You should learn about proper join syntax and to prefix all columns with table aliases. A better way to write the second query is:
SELECT ris.id, COUNT(*) as numberOfUsers
FROM (SELECT switch_id, port_id, s.service, s.id
FROM traffic t join
isp_service s
on s.id = t.isp_service_id
WHERE datetime >= '2013-09-01 00:00:00' AND datetime < '2013-09-02 00:00:00'
GROUP BY switch_id, port_id
) ris
GROUP BY ris.id
ORDER BY ris.id;
This query has a problem, because s.service and s.id are included in the select, but they are not in the group by. That means that MySQL takes arbitrary values for them.
It is unclear what specifies a "user". If the switch_id/port_id pair identifies a user, then the query should produce correct results. However, you are likely to be missing id values that have users. You might be able to do this in one query:
SELECT s.id, count(*) as NumberOfUsers, count(distinct switch_id, port_id) as NumberOfUsers2
FROM traffic t join
isp_service s
on s.id = t.isp_service_id
WHERE datetime >= '2013-09-01 00:00:00' AND datetime < '2013-09-02 00:00:00'
GROUP BY s.id;
I am not sure which count is most appropriate.

Mysql count() fetches wrong result

I am trying to find the number of records for current week.
My current query is:
SELECT Week(Str_to_date(products_options_values, '%m-%d-%Y'), 1) AS order_week,
Year(Str_to_date(products_options_values, '%m-%d-%Y')) AS order_year,
order_active,
Count(op.sub_order_id) AS deliveries
FROM orders_products_attributes opa
LEFT JOIN orders_products op
ON ( opa.orders_products_id = op.orders_products_id )
GROUP BY order_week,
order_year
HAVING order_week = '31'
AND order_year >= '2013'
AND order_active = 0
ORDER BY order_week
It fetches deliveries AS 2 where as there are actually 4 records, and if I run the same query after removing COUNT and GROUP BY, it correctly shows all 4 rows. The same problem happens on other weeks too, for example week 34 has 3 records, but the above query fetches it as 4 instead. Moreover, another weird thing is, in the GROUP BY clause, if I remove either one of order_week or order_year the query returns an empty result set.
Any idea what I am doing wrong?
Try to move all HAVING conditions into WHERE. Also Count(id) - counts UNIQUE values of ID not all. If you need all records count just use COUNT(*)
SELECT Week(Str_to_date(products_options_values, '%m-%d-%Y'), 1) AS order_week,
Year(Str_to_date(products_options_values, '%m-%d-%Y')) AS order_year,
order_active,
Count(op.sub_order_id) AS deliveries
FROM orders_products_attributes opa
LEFT JOIN orders_products op
ON ( opa.orders_products_id = op.orders_products_id )
WHERE order_week = '31'
AND order_year >= '2013'
AND order_active = 0
GROUP BY order_week,
order_year
ORDER BY order_week