Access Update query with left join and group by - ms-access

The query that selects the 42 unique task codes from [Task_History_Report_063018] that DO NOT currently exist in the [Task Code Dict] is
SELECT Task_History_Report_063018.[Task code]
FROM Task_History_Report_063018 LEFT JOIN [Task Code Dict]
ON Task_History_Report_063018.[Task code] = [Task Code Dict].[Task Code]
WHERE ((([Task Code Dict].[Task Code]) Is Null))
GROUP BY Task_History_Report_063018.[Task code];
When I convert this to the following update query:
UPDATE Task_History_Report_063018 LEFT JOIN [Task Code Dict]
ON Task_History_Report_063018.[Task code] = [Task Code Dict].[Task Code]
SET [Task Code Dict].[Task Code] = [Task_History_Report_063018].[Task code]
WHERE ((([Task Code Dict].[Task Code]) Is Null));
It attempts to update the dictionary with 201 NON-UNIQUE task codes. These are the 42 unique codes, expanded by their duplicates.
I tried:
UPDATE (SELECT Task_History_Report_063018.[Task code]
FROM Task_History_Report_063018
GROUP BY Task_History_Report_063018.[Task code]) as GroupedTasks
LEFT JOIN [Task Code Dict]
ON GroupedTasks.[Task code] = [Task Code Dict].[Task Code] SET [Task Code Dict].[Task Code] = GroupedTasks.[Task code]
WHERE ((([Task Code Dict].[Task Code]) Is Null));
When I select the Datasheet View I see the 42 null records for the corresponding unique task codes that are new, but when I attempt to execute I get an error that says:
Operation must use an updateable query.
I think this question was addressed here for MySQL, but the syntax didn't totally translate... MySQL Update query with left join and group by

Okay, fixed this. For some reason I was trying to do an update query when I was supposed to be doing and append. This got the job done:
INSERT INTO [Task Code Dict] ( [Task Code] )
SELECT DISTINCT Task_History_Report_063018.[Task code]
FROM Task_History_Report_063018 LEFT JOIN [Task Code Dict]
ON Task_History_Report_063018.[Task code] = [Task Code Dict].[Task Code]
WHERE ((([Task Code Dict].[Task Code]) Is Null));

Related

[34, 105] The expression is not a valid conditional expression

Hi guys i am getting the error :
Exception Description: Syntax error parsing [SELECT u FROM Appointment U WHERE u.startDatetime BETWEEN :date1 AND :date2 INNER JOIN Users_appointment where u.ATTENDEES_USER_NAME LIKE :search].
[34, 105] The expression is not a valid conditional expression.
when i am trying to run the query
public List<Appointment> appointmentRangeSearch(Date startdatetime, Date endDate) {
Query q = em.createQuery("SELECT u FROM Appointment U WHERE u.startDatetime BETWEEN :date1 AND :date2 INNER JOIN Users_appointment where u.ATTENDEES_USER_NAME LIKE :search");
q.setParameter("search", "%" + searchString + "%");
q.setParameter("date1", startdatetime, TemporalType.TIMESTAMP);
q.setParameter("date2", endDate, TemporalType.TIMESTAMP);
return q.getResultList();
}
the idea is that i search for a range of dates in the appointment table and then see if there is a matching username in the users_appointment table and if so output this
what is going wrong ?
thanks
Wrong SQL syntax used. Please go through the SQL syntax. You need to add a JOINING clause using ON to tell mysql how to link appointment table with users_appointment table. I assume that you have userid column in both tables.
SELECT u FROM Appointment U INNER JOIN Users_appointment
ON u.userid = users_appointment.userid
WHERE u.startDatetime BETWEEN :date1 AND :date2
AND u.ATTENDEES_USER_NAME LIKE :search

Error when trying to run an update query using innerjoin (MySQL)

I try to use the following code in a MySQL query but get the error "Operation must use an updateable query" when I try to run it. However if I create another simple update query (without joins and subqueries) it works fine. Stumped at this point. Any ideas?
UPDATE IPad
SET Ipad.[case number] = (
SELECT ipad_damage_history.[case number]
FROM IPad
INNER JOIN ipad_damage_history ON IPad.[Apple ID] = ipad_damage_history.[Apple ID]
WHERE IPad.[case number] IS NULL
AND IPad.[Apple ID] = ipad_damage_history.[Apple ID]
)
WHERE Ipad.[Apple ID] = (
SELECT ipad_damage_history.[Apple ID]
FROM IPad
INNER JOIN ipad_damage_history ON IPad.[Apple ID] = ipad_damage_history.[Apple ID]
WHERE IPad.[case number] IS NULL
AND IPad.[Apple ID] = ipad_damage_history.[Apple ID]
);
The [] around identifiers is a SQL SERVER thing. In mysql you should use ` around multi word columns or reserved keywords.
And mysql update allows you to do the inner join directly:
UPDATE IPad
INNER JOIN ipad_damage_history
ON IPad.`Apple ID` = ipad_damage_history.`Apple ID`
SET Ipad.`case number` = ipad_damage_history.`case number`
WHERE IPad.`case number` IS NULL
AND IPad.`Apple ID` = ipad_damage_history.`Apple ID`

Using `includes` instead of `joins` and using sql `SUM` method to avoid N+1

I've got some old legacy code to which I've added additional parameters (i've removed unnecessary parts):
Farm.joins("LEFT JOIN ( SELECT farm_id, SUM(kwota) as suma_wplat FROM payments GROUP BY farm_id) as kwoty ON kwoty.farm_id = farms.id").
select("farms.id, kwoty.suma_wplat").includes(:certificate).where("certificates.data_wyslania IS null")
That will produce such query:
"SELECT farms.id, kwoty.suma_wplat FROM `farms` LEFT JOIN ( SELECT farm_id, SUM(kwota) as suma_wplat FROM payments GROUP BY farm_id) as kwoty ON kwoty.farm_id = farms.id WHERE (certificates.data_wyslania IS null)"
Unfortunately that will fail as suma_wplat is not available later (returned objects consist of all Farm attributes).
If I'll change includes to joins produced query will look like that:
"SELECT farms.id, kwoty.suma_wplat FROM `farms` INNER JOIN `certificates` ON `certificates`.`farm_id` = `farms`.`id` AND `certificates`.`year` = '2013' LEFT JOIN ( SELECT farm_id, SUM(kwota) as suma_wplat FROM payments GROUP BY farm_id) as kwoty ON kwoty.farm_id = farms.id WHERE (certificates.data_wyslania IS null)"
and now Farm consists of proper fields (together with counted sum suma_wplat) but it results in N+1 queries.
How can I resolve that? For now I can only think about adding another column to Farm with counted value, but that w'd be a workaround, not true solution.
Edit: Whole query looks now like this:
Farm.joins("LEFT JOIN ( SELECT farm_id, SUM(kwota) as suma_wplat FROM payments GROUP BY farm_id) as kwoty ON kwoty.farm_id = farms.id").select("farms.id, kwoty.suma_wplat").map do |f|
(...)
f.suma_wplat
end

Print all rows from one table with a nested MySQL query

I have a MySQL query that I would like to enhance by requiring that all values of client.client_name are printed out in the result, even if no values are found for every row in that table. The current table shows:
client.client_name
Client A
Client B
Client C
The current MySQL query is below:
SELECT X.expr1 AS 'Project Name', SUM(X.expr2) AS 'Total Hours Logged', X.expr3 - sum(X.expr2) AS 'Monthly Hours Remaining', X.expr4 AS 'Last Day', DATEDIFF(X.expr4 , curdate()) AS 'Days Remaining'
FROM
(SELECT
client.client_name AS expr1
, sum(time_records.value) AS expr2
, client.monthly_hours AS expr3
FROM project_objects
INNER JOIN projects
ON projects.id = project_objects.project_id
INNER JOIN time_records
ON time_records.parent_id = project_objects.id
LEFT JOIN client
ON project_objects.project_id = client.project_id
WHERE time_records.parent_type = 'Task'
AND client.start_day_of_month < dayofmonth(curdate())
AND time_records.state = 3
GROUP BY client.client_name
UNION
SELECT
client.client_name AS expr1
, sum(time_records.value) as expr2
, client.monthly_hours AS expr3
FROM projects
INNER JOIN time_records
ON projects.id = time_records.parent_id
LEFT JOIN client
ON projects.id = client.project_id
WHERE time_records.parent_type = 'Project'
AND client.start_day_of_month < dayofmonth(curdate())
AND time_records.state = 3
GROUP BY client.client_name
) X
GROUP BY X.expr1
ORDER BY DATEDIFF(X.expr4 , curdate()
As you can see from the above query - I added a Left Join for the client table, however it doesn't result in printing out all client records - it only prints those for which there are time_records available. I think this is related to the nesting or the order of how I am writing the joins, but can't seem to figure it out. If you have any ideas it would be greatly appreciated. Thanks!
Please try order as below:
FROM client LEFT JOIN project_objects
ON project_objects.project_id = client.project_id
see SQLFiddle for the final solution here: http://sqlfiddle.com/#!2/30362/16

Why Rails ActiveRecord generates 'count(distinct model.id)' for '.count' when 'includes' is used

I am using Rails 3.0.11 with MySQL 5.1 and today I realized that it generates an unexpected SQL statement when calling count on a ActiveRecord::Relation.
More details:
I have the model Profile which belongs to an Account. Assuming that I do the following:
p = Profile.includes(:account).where("accept_threshold >= 0")
p.count
(accept_threshold is an attribute of Profile)
the generated SQL statement is:
SELECT COUNT(DISTINCT `profiles`.`id`) FROM `profiles` LEFT OUTER JOIN `accounts` ON `accounts`.`id` = `profiles`.`account_id` WHERE (accept_threshold >= 0)
This is really a surprise to me. I would expect:
SELECT COUNT(*) FROM `profiles` LEFT OUTER JOIN `accounts` ON `accounts`.`id` = `profiles`.`account_id` WHERE (accept_threshold >= 0)
On the other hand, the following piece of code:
p = Profile.where("accept_threshold >= 0")
p.count
generates
SELECT COUNT(*) FROM `profiles` WHERE (accept_threshold >= 0)
Do you know why is this the case?
How can I force it to generate COUNT(*) instead of COUNT(DISTINCT `profiles`.`id`)?
I have tried
p.count(:select => "*")
but it does not work.
If it didn't do a count distinct it would be count of the number of account records where the accept_threshold is >= 0.
You are after a count of profile records, not a count of account records.