mysql query doesnot work - mysql

This is my mysql query!
SELECT projects.projects_id,
projects.projects_title,
projects.projects_cost
FROM projects
LEFT JOIN invoice
ON invoice.projects_id = projects.projects_id
LEFT JOIN project_assign
ON project_assign.projects_id=projects.projects_id
WHERE project_assign.assigned_user_id=3
AND (SUM( invoice.invoice_amount) < projects.projects_cost
OR invoice.projects_id is null )
AND project_assign.project_completed_date IS NOT NULL
In this query i want select all row that:
Is not present in other table e.g. (in my case other table is
"invoice")
Or if persent then this condition must hold sum(invoice.invoice_amount) < projects.projects_cost
Thanks.

Divide your problem. Use a UNION. First use one query to select all records that are not present in the first table (Use a LEFT JOIN), union that with the result of your second query which would give you all records meeting your second condition (use an outer join)
//Select all records present in left table
//union
//select all records present in both tables matching your condition.
SELECT projects.projects_id,
projects.projects_title,
projects.projects_cost
FROM projects
LEFT JOIN invoice
ON invoice.projects_id = projects.projects_id
LEFT JOIN project_assign
ON project_assign.projects_id=projects.projects_id
WHERE project_assign.assigned_user_id=3
AND project_assign.project_completed_date IS NOT NULL
UNION
SELECT projects.projects_id,
projects.projects_title,
projects.projects_cost
FROM projects
INNER JOIN invoice
ON invoice.projects_id = projects.projects_id
INNER JOIN project_assign
ON project_assign.projects_id=projects.projects_id
WHERE project_assign.assigned_user_id=3
AND (SUM( invoice.invoice_amount) < projects.projects_cost
AND project_assign.project_completed_date IS NOT NULL

select projects.projects_id, projects.projects_title,projects.projects_cost
from projects
left join invoice
on invoice.projects_id = projects.projects_id
left join project_assign
on project_assign.projects_id=projects.projects_id
where project_assign.assigned_user_id=3 and
((select sum(invoice.invoice_amount) from invoice) < projects.projects_cost or invoice.projects_id is null )
and project_assign.project_completed_date is not null

You cannot put aggregation functions in the where clause. In this case, you can do the aggregation using a subquery and then do the comparison:
SELECT p.projects_id, p.projects_title, p.projects_cost
FROM projects p LEFT JOIN
(select i.projects_id, sum(invoice_amount) as invoice_amount
from invoice i
) i
ON i.projects_id = p.projects_id LEFT JOIN
project_assign pa
ON pa.projects_id = p.projects_id
WHERE pa.assigned_user_id = 3 AND
(i.invoice_amount < p.projects_cost OR i.projects_id is null ) AND
pa.project_completed_date IS NOT NULL;

Related

How to exclude a record with INNER/LEFT JOIN

There's a table called order_flags that I am trying to join with orders table with orders.id being the foreign key in order_flags as order_fk. All I need is to exclude an order whose foreign key record has value 7 set for 'order_flags.flag' field. The SQL that I am trying below returns empty records. I expect this to return all the records except for the one having 7 as value for flag field in order_flags table. Tables in the question are:
SELECT orders.id,
orders.po_number,
orders.payment_method,
order_flags.flag,
order_details.vendor_fk,
Max(order_details.estimated_shipped_date) AS estimated_shipped_date,
Max(back_orders.back_order_date) AS back_order_date
FROM orders
INNER JOIN order_details
ON order_details.order_fk = orders.id
LEFT JOIN order_flags
ON order_flags.order_fk = orders.id
LEFT JOIN sku
ON sku.item_sku = order_details.sku
LEFT JOIN back_orders
ON back_orders.sku_fk = sku.id
WHERE orders.order_status = 'PL'
AND ( ( order_details.item_status = 'PL' )
OR ( order_details.item_status = 'SN' ) )
AND orders.placed_date >= '1969-07-03'
AND orders.flag_overdue_po = '1'
AND order_details.estimated_shipped_date != '0000-00-00'
AND order_details.vendor_fk NOT IN ( '57', '0', '72', '161' )
AND order_flags.flag != '7'
GROUP BY orders.id,
order_details.vendor_fk
If in a WHERE clause you mention a column from a LEFT JOINed table, you convert the join to INNER JOIN.
You have this.
FROM orders
...
LEFT JOIN order_flags
ON order_flags.order_fk = orders.id
...
WHERE ... order_flags.flag != '7'
Try moving the filter to the ON clause like this.
FROM orders
...
LEFT JOIN order_flags
ON order_flags.order_fk = orders.id
AND order_flags.flag != '7'
...
WHERE ...
Or try this...
WHERE ... (order_flags.flag IS NULL OR order_flags.flag != '7')
Why does this happen? If no row from the left of the LEFT JOIN matches a row from the right, the resultset of the join has NULLs for the columns from the left. NULLs are weird. They're not equal to anything, and they're not unequal to anything. So your WHERE filter eliminated lots of rows.

Mysql Select unique record based on multiple columns and display only group and sum amount

Hi I am trying to query a table that conatains multiple duplicates on Code,Amount and Status How will I do this if I only one to get a result group according to the client_group name and get the sum of amount under that group
SELECT `client`.`client_group`
, FORMAT(SUM(`Data_result`.`Data_result_amount` ),2) as sum
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
GROUP BY `client`.`client_group`
Result of said query:
Table
Try to distinct before run the 'sum' check whether this solve your problem
SELECT `client_group` , FORMAT(SUM(`Data_result_amount` ),2) as sum from (
SELECT DISTINCT `client`.`client_group` , `Data_result`.`Data_result_amount`
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
) T
GROUP BY `client_group`
you can check the query here http://sqlfiddle.com/#!9/36a3f8/6

Mysql subquery for sum all columns in inner Join

I am attempting to get the sum of 12 columns (in same table) in a subquery in an inner join.
Here is a link to my schema :
SqlFiddle
The query I am attempting to use is this:
SELECT
`inventory`.`part_number`,
`inventory`.`qty`,
`inventory`.`description`,
`reorder`.`reorder_point` * '1' `point`,
`inventory`.`cost`,
`vendor`.`name` AS `vendor_name`, SELECT (SUM(`saleshistory`.`Sales_1_Month_Prior`)+SUM(`saleshistory`.`Sales_2_Month_Prior`)+SUM(`saleshistory`.`Sales_3_Month_Prior`)+SUM(`saleshistory`.`Sales_4_Month_Prior`)+SUM(`saleshistory`.`Sales_5_Month_Prior`)+SUM(`saleshistory`.`Sales_6_Month_Prior`)+SUM(`saleshistory`.`Sales_7_Month_Prior`)+SUM(`saleshistory`.`Sales_8_Month_Prior`)+SUM(`saleshistory`.`Sales_9_Month_Prior`)+SUM(`saleshistory`.`Sales_10_Month_Prior`)+SUM(`saleshistory`.`Sales_11_Month_Prior`)+SUM(`saleshistory`.`Sales_12_Month_Prior`) AS TTL
FROM `inventory`
LEFT JOIN `reorder` ON `inventory`.`part_number` = `reorder`.`part_number`
LEFT JOIN `vendor` ON `inventory`.`vendor` = `vendor`.`vendor_id`
INNER JOIN `saleshistory` ON `saleshistory`.`location` = `inventory`.`location` AND `saleshistory`.`part_number` = `inventory`.`part_number`
WHERE `inventory`.`qty` <= `reorder`.`reorder_point`
AND `inventory`.`location` = '99'
AND `reorder`.`reorder_point` != '0'
GROUP BY `inventory`.`part_number`
ORDER BY `vendor`.`name` ASC
When using this query, it returns all the values for all the records not just the rows.

MySQL - WHERE every value is IN

The following query selects all workunts where the inputs are "done" (subquery on line 7). This works fine... when there is only one input. How can I change this so that it requires every input to be IN that set returned by the subquery, not just one of the inputs to be present?
SELECT workunits.ID
FROM workunits
LEFT JOIN workunitInputs ON workunits.ID = workunitInputs.workunitID
WHERE workunits.ID NOT IN (SELECT workunitID FROM jobworkunitassoc)
AND (
workunitInputs.inputID IN (
SELECT workunitOutputs.outputID
FROM workunitOutputs
LEFT JOIN workunits ON workunitOutputs.workunitID = workunits.ID
LEFT JOIN jobworkunitassoc ON workunits.ID = jobworkunitassoc.workunitID
LEFT JOIN jobs ON jobworkunitassoc.jobID = jobs.ID
WHERE jobs.done = 1
)
OR workunitInputs.inputID IS NULL
)
GROUP BY workunits.ID
Thanks, Istvan.
Change that clause to:
AND (
workunitInputs.inputID NOT IN (
SELECT workunitOutputs.outputID
FROM workunitOutputs
LEFT JOIN workunits ON workunitOutputs.workunitID = workunits.ID
LEFT JOIN jobworkunitassoc ON workunits.ID = jobworkunitassoc.workunitID
LEFT JOIN jobs ON jobworkunitassoc.jobID = jobs.ID
WHERE jobs.done != 1
)
This is based on the logical tautology: All X in Y === No X in !Y
This query works for me, though it may not be the best solution:
http://pastebin.com/g9qBjQGU

SQL query wrong result

i have this query:
SELECT `completed`.`ID` AS `ID`,`completed`.`level` AS `level`,`completed`.`completed_in` AS `completed_in`, COUNT(1) AS `right_answers_num`
FROM `completed`
INNER JOIN `history` ON `history`.`ID` = `completed`.`ID`
INNER JOIN `questions` ON `questions`.`ID` = `history`.`question`
WHERE `completed`.`student_id` = '1' AND `questions`.`answer` = `history`.`answer`
GROUP BY `completed`.`ID`
ORDER BY `completed`.`completed_in` DESC
what i need is to get info of each test in completed table (id,level,completed_in,right_answer_num)
the problem with that query is that if there is no one right answer(history.answer = questions.answer) then it doesn't return the row, while it should return the row(id,level,completed_in) and the right_answer_num(counter) should be zero..
please help me,, thanks ahead.
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question AND questions.answer = history.answer
WHERE
completed.student_id = '1'
GROUP BY
completed.ID
ORDER BY completed.completed_in DESC
use a LEFT OUTER JOIN intead of an INNER JOIN.
The second inner join is what's causing rows with no record in the questions table to be omitted. An inner join will only return rows that have data in all corresponding tables. Change the second inner join to a left join like so:
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question
WHERE completed.student_id = 1
GROUP BY completed.ID
ORDER BY completed.completed_in DESC