mysql add condition for derived max function column - mysql

I have the following sql which is not working on the where condition.
SELECT t.PROJID,sum(t.UNITS) AS totalunits, sum(t.COST) AS totalcost, project, max(t.DATE) as lastupdated, PROJCODE
FROM `projectcosts` `t`
left join projects on projects.PROJID = t.PROJID
where lastupdated LIKE '%2014-06-11%'
GROUP BY t.PROJID

You should not use like on dates. The right solution is to simply truncate the date and do the comparison. However, you need to use the field in the data:
SELECT t.PROJID, sum(t.UNITS) AS totalunits,
sum(t.COST) AS totalcost, project, max(t.DATE) as lastupdated, PROJCODE
FROM `projectcosts` `t` left join
projects on projects.PROJID = t.PROJID
where date(t.date) = date('2014-06-11')
GROUP BY t.PROJID;
Or, if you have an index on lastupdated, using a range allows the use of the index:
SELECT t.PROJID, sum(t.UNITS) AS totalunits,
sum(t.COST) AS totalcost, project, max(t.DATE) as lastupdated, PROJCODE
FROM `projectcosts` `t` left join
projects on projects.PROJID = t.PROJID
where t.date >= date('2014-06-11') and t.date < date('2014-06-12')
GROUP BY t.PROJID;
You might really be wanting to use having, which is suggested by the use of the column alias instead of the base column. In that case:
SELECT t.PROJID, sum(t.UNITS) AS totalunits,
sum(t.COST) AS totalcost, project, max(t.DATE) as lastupdated, PROJCODE
FROM `projectcosts` `t` left join
projects on projects.PROJID = t.PROJID
GROUP BY t.PROJID
HAVING date(lastupdated) = date('2014-06-11');

Like can never be used with date field.
If you are changing the type to vachar it is possible

Related

column "d.discount_amount" must appear in the GROUP BY clause or be used in an aggregate function

I have written this query to find the payment using two different table ,
SELECT (SUM(o_p.price) - d.discount_amount) as payment
FROM order_products as o_p
LEFT JOIN discounts as d ON O_p.order_id = d.order_id
GROUP BY o_p.order_id
It shows an error column "d.discount_amount" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT o_p.order_id, (SUM(price) - d.discount_amount) as pay...
9:23 PM
Any suggestions, please?
select t1.sm - t2.discount_amount
from (
select t1.order_id,
sum(t1.price) sm
from order_products t1
order by t1.order_id) t1 left join discounts t2 on t1.order_id = t2.order_id

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;

Use aggregate values for farther calculation

I have the followin query:
SELECT contracts.id,
(SELECT sum(pos.sum_to_pay) FROM pos
where pos.contract_id=contracts.id and pos.is_draft=0) as paid,
(SELECT sum(acts.amount) FROM acts
where acts.contract_id=contracts.id) as acts_sum
from contracts
it works but i want to add another result field to_pay that should be calculated like acts_sum - paid = to_pay.
I'm trying to do it like this:
SELECT contracts.id,
(SELECT sum(pos.sum_to_pay) FROM pos
where pos.contract_id=contracts.id and pos.is_draft=0) as paid,
(SELECT sum(acts.amount) FROM acts
where acts.contract_id=contracts.id) as acts_sum,
(acts_sum - paid) as to_pay
from contracts
but I got the error Unknown column 'acts_sum'. How can i find to_pay value based on acts_sum and paid?
Do it with a subquery like this
SELECT acts_sum, paid, (acts_sum - paid) as to_pay FROM
(SELECT contracts.id,
(SELECT sum(pos.sum_to_pay) FROM pos
where pos.contract_id=contracts.id and pos.is_draft=0) as paid,
(SELECT sum(acts.amount) FROM acts
where acts.contract_id=contracts.id) as acts_sum,
from contracts ) subq
You could rewrite your query using joins, correlated sub queries sometimes considered as a costly solution
select c.id,
COALESCE(a.acts_sum,0),
COALESCE(p.paid,0),
COALESCE(a.acts_sum,0) - COALESCE(p.paid,0) as to_pay
from contracts c
left join (
SELECT contract_id,sum(sum_to_pay) paid
FROM pos
where is_draft=0
group by contract_id
) p on c.id = p.contract_id
left join (
SELECT contract_id,sum(amount) acts_sum
FROM acts
group by contract_id
) a on c.id = a.contract_id

GROUP BY ordering

I have the following query in mysql:
select territory_id, platform_type_id, p.store_url
from main_itemmaster m
inner join main_iteminstance i on m.id=i.master_id
inner join main_territorypricing p on p.item_id=i.id
inner join main_territorypricingavail a on a.tp_id=p.id
where imdb_url = 'http://imdb.com/title/tt1576422/'
group by platform_type_id
Which gives me the following:
territory_id platform_type_id store_url
US Amazon http://www.amazon.com/dp/B00EQIHJAG
PT ITUNES https://itunes.apple.com/pt/movie/id582142080
However, I want to do a GROUP BY to return the territory_id="US" first if that exists. How would I do that?
This is one way I tried which looks quite dirty but does work in the version of mysql I'm using:
select * from
(select territory_id, platform_type_id, p.store_url from main_itemmaster m
inner join main_iteminstance i on m.id=i.master_id
inner join main_territorypricing p on p.item_id=i.id
inner join main_territorypricingavail a on a.tp_id=p.id
where imdb_url = 'http://imdb.com/title/tt1576422/'
order by territory_id='us' desc
) x group by platform_type_id
Which gives:
territory_id platform_type_id store_url
US Amazon http://www.amazon.com/dp/B00EQIHJAG
US ITUNES https://itunes.apple.com/us/movie/id582142080
Which is the correct result set I'm looking to get.
Here is a link to a SQL fiddle. I condensed all the data into one table to focus on the GROUP BY statement: http://sqlfiddle.com/#!9/81c3b6/2/0
So from the comments and the addition of the SqlFiddle it actually seems like you want to create a partitioned row number with a precedence on US per platform and then select the first record. One way of doing partitioned Row Numbers in mysql is to use variables here is an example:
SELECT
territory_id
,platform_type_id
,store_url
FROM
( SELECT
*
,#PlatFormRowNum:= IF(#prevplatform = platform_type_id, #PlatFormRowNum + 1, 1) as PlatformRowNum
,#prevplatform:= platform_type_id
FROM
main_itemmaster m
CROSS JOIN (SELECT #prevplatform:='',#PlatFormRowNum=0) var
ORDER BY
platform_type_id
,CASE WHEN territory_id = 'US' THEN 0 ELSE 1 END
,territory_id
) t
WHERE
t.PlatformRowNum = 1
ORDER BY
t.platform_type_id
SQL Fiddle: http://sqlfiddle.com/#!9/81c3b6/12
Basically this partitions the row number by platform, orders US before any other territory and then selects the first row foreach platform. The one question/trick is how do you choose which to return when US is not available for the platform simply the ascending alphabetical order of the territory_id?

Latest date from ClassSchedule Table for each class

I have a problem with database query?
Here is the Scenario
This is a TeacherClass Table (Parent Table)(id)
And This is a ClassSchedule Table(Child table)(teacher_class_id is a foreign key)
I want to find out the the latest date from ClassSchedule Table for each class and order by class_schdule_date(latest date).
(It would be better for me if you write the query in cackphp query syntax.)
Please Help me.
This requires a straightforward join:
select tc.id, max(schedule_date) as max_schedule_date
from TeacherClass tc
left join ClassSchedule cs on cs.teacher_class_id = tc.id
group by tc.id
You can select other columns from the TeacherClass table as you like - just add them to the group by clause too.
Note that left join is required in case there are no scheduled dates for the class, you still get a row for the class (but the max scheduled date will be null)
Use this solution:
SELECT
c.*, b.*
FROM
(
SELECT teacher_class_id, MAX(schedule_date) AS maxdate
FROM classschedule
GROUP BY teacher_class_id
) a
INNER JOIN
classschedule b ON
a.teacher_class_id = b.teacher_class_id AND
a.maxdate = b.schedule_date
INNER JOIN
teacherclass c ON
b.teacher_class_id = c.teacher_class_id