Built in Functions and Grouping is not working in Microsoft Access - mysql

I am trying to select from three tables using inner join in Microsoft Access. in one of the fields, i also need to select how many records did it return.
SELECT Person.FirstName, Person.LastName, Person.Phone,
Person.Email,Person.Address, Room.RoomNo, Room.Type, Building.Name,
Floor.Name,count(*) as result
FROM (Floor INNER JOIN (Building INNER JOIN
Room ON Building.BuildingID = Room.BuildingID) ON Floor.FloorNo =
Room.FloorNo) INNER JOIN (Person INNER JOIN Patient ON Person.Username =
Patient.Username) ON Room.RoomNo = Patient.RoomNo
WHERE (((Person.FirstName) Like "*" & [Forms]![search]![firstnameKey] & "*")
AND ((Person.LastName) Like "*" & [Forms]![search]![lastnameKey] & "*")) AND
(patient.status = 1)
GROUP BY Patient.username ;

Any time you have an aggregate function you'll have to group by the fields not being calculated. Just from looking at your select statement you are returning multiple fields, i.e: Person.Firstname, Person.Lastname etc. I believe you will have to group by those non-aggregated fields.
Sample Code:
SELECT Person.FirstName, Person.LastName, Person.Phone, Person.Email, Person.Address, Count(*) as Result <br>
From Table1 join table 2 -- etc <br>
WHERE a = b -- etc <BR>
GROUP BY Person.FirstName, Person.LastName, Person.Phone, Person.Email, Person.Address

Related

SQL - Where have i gone wrong

QUESTION: I need to display the customers name and the total cost of the products they have ordered when they exceed over £10.
I cannot tell if it is because I am trying to use an inner join for three tables?
My attempt:
SELECT
DISTINCT Customer.custName,
SUM(Orders.quantity * Product.cost)
FROM
Customer,
Product
INNER JOIN Orders ON Product.productNo = Orders.productNo
WHERE
(Product.productNo = Orders.productNo)
AND (Orders.quantity * Product.cost > 10);
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax. Plus, use GROUP BY. And your JOIN conditions are not complete. So:
SELECT c.custName, SUM(o.quantity * p.cost)
FROM Customer c JOIN
Orders o
ON o.customerNo = c.customerNo JOIN
Product p
ON p.productNo = o.productNo
GROUP BY c.custName
HAVING SUM(o.quantity * p.cost) > 10;

Appending rows returned from different queries into one

I am having 3 queries, which takes data from 3 different tables (with joins) and their column names are pretty much same (or I made them same by using ASkeyword). Once the 3 queries are completed, I want to combine their results, so it looks like they are coming from one table. Please have a look at the below codes.
1st Query
SELECT Client_Portfolio.*,
Client.Name,
Provider.Name,
"One" AS Income_Type,
One.`One_Gross_Fee` AS "Gross_Fee",
One.`One_V_Fee` AS "V_Fee",
One.`One_E_Fee` AS "E_Fee",
One.`One_I_Fee` AS "I_Fee",
One.`One_Tax_Provision` AS "Tax_Provision",
One.`One_Net_Income` AS "Net_Income",
"N/A" AS VAT,
One.`Updated_Date`
FROM Client_Portfolio
INNER JOIN Portfolio ON Portfolio.`idPortfolio` = Client_Portfolio.`idPortfolio`
INNER JOIN Client ON Client.idClient = Client_Portfolio.idClient
JOIN Provider ON Provider.idProvider = Portfolio.idProvider
INNER JOIN One ON One.idPortfolio = Portfolio.idPortfolio
2nd Query
SELECT Client_Portfolio.*,
Client.Name,
Provider.Name,
"Two" AS Income_Type,
Two.`Two_Gross_Fee` AS "Gross_Fee",
Two.`Two_V_Fee` AS "V_Fee",
Two.`Two_E_Fee` AS "E_Fee",
Two.`Two_I_Fee` AS "I_Fee",
Two.`Two_Tax_Provision` AS "Tax_Provision",
Two.`Two_Net_Income` AS "Net_Income",
Two.`Two_Vat` AS VAT,
Two.`Updated_Date`
FROM Client_Portfolio
INNER JOIN Portfolio ON Portfolio.`idPortfolio` = Client_Portfolio.`idPortfolio`
INNER JOIN Client ON Client.idClient = Client_Portfolio.idClient
JOIN Provider ON Provider.idProvider = Portfolio.idProvider
INNER JOIN Two ON Two.idPortfolio = Portfolio.idPortfolio
3rd Query
SELECT Client_Portfolio.*,
Client.Name,
Provider.Name,
"Three" AS Income_Type,
Three.`Three_Gross_Fee` AS "Gross_Fee",
"N\A" AS "V_Fee",
Three.`Three_E_Fee` AS "E_Fee",
"N\A" AS "I_Fee",
Three.`Three_Tax_Provision` AS "Tax_Provision",
Three.`Three_Net_Income` AS "Net_Income",
Three.`Three_Vat` AS VAT,
Three.`Updated_Date`
FROM Client_Portfolio
INNER JOIN Portfolio ON Portfolio.`idPortfolio` = Client_Portfolio.`idPortfolio`
INNER JOIN Client ON Client.idClient = Client_Portfolio.idClient
JOIN Provider ON Provider.idProvider = Portfolio.idProvider
INNER JOIN Three ON Three.idPortfolio = Portfolio.idPortfolio
Once these queries are done, I want to combine their results. Which means, Rows returned by the 2nd Query will be appended after the rows returned by the 1st query. Rows returned by the 3rd query will be appended after the rows returned by the 2nd query. Finally, I want to sort the final result by Updated_Date
How can I do this?
Use UNION to combine the queries:
SELECT one_fields FROM Client_Portfolio ...
UNION
SELECT two_fields FROM Client_Portfolio ...
UNION
SELECT three_fields FROM Client_Portfolio ...
Sorting can be done by appending an order by clause after the last query, as follows:
SELECT one_fields FROM Client_Portfolio ...
UNION
SELECT two_fields FROM Client_Portfolio ...
UNION
SELECT three_fields FROM Client_Portfolio ...
ORDER BY field1, field2, field3...;
Note that field1, field2... can be field names or field numbers (starting from 1).

How to convert code written in INNER JOIN to Subquery

Need some help with converting code from Join statement into Subquery.
I need to remove GROUP BY from it somehow, when converted into Subquery and don't know how.
Managed to put small portion of subquery at the end of the code, don't know how to do rest.
Need some help, thank you.
Here is the sample of the code: (need to convert into SQL Server syntax)
SELECT
b.Number, t.IDTyre, SUM(c.Price)
FROM Tyre AS t
INNER JOIN Bill AS b ON t.BillID = b.IDBill
INNER JOIN Customer AS c ON c.TyreID = t.IDTyre
GROUP BY b.Number, t.IDTyre
HAVING SUM(c.Price) < 3000 OR t.IDTyre NOT IN (SELECT c.TyreID FROM Customer AS c)
Check if the below query works:
SELECT
(Select b.Number From Bill AS b Where b.IDBill = t.BillID) as Number,
t.IDTyre as TyreID,
(Select SUM(c.Price) From Customer AS c Having SUM(c.Price) < 3000 OR t.IDTyre NOT IN (SELECT Distinct c.TyreID FROM Customer AS c) And c.TyreID = t.IDTyre) as Price
FROM Tyre AS t
Why are you trying to convert this to Sub Query?
JOINS are the best options while dealing with linking tables.
Also the "NOT IN" that you are trying to do at the end is also not good, you should use "NOT EXISTS". Change this to: OR NOT EXISTS (SELECT * FROM Customer AS c WHERE t.IDTyre=c.TyreID)

Getting SUM of two distinct procedure

I have two procedures that calculate two data. Now i would like to get the sum of those two output. Is it possible in sql?
ex:
Select bio.*,
SUM (cnt_report,cnt_report_2) as TOTAL --CAN I DO THIS?
cnt_report + cnt_report_2 as Total --This doesn't seem to work
from biographical bio
LEFT JOIN (
SELECT cr.id, COUNT (*) AS cnt_report
FROM report cr
GROUP BY cr.id
) cr11 ON bio.id = cr11.id
LEFT JOIN (
SELECT cr.id2,
COUNT (*) AS cnt_report_2
FROM report cr
GROUP BY cr.id2
) cr11 ON bio.id = cr11.id2
Your Sum function will work with a little tweak, but you will need to add a GROUP BY line at the end. Also, you seem to have named your two sub queries with the same alias. Try this:
Select bio.*,
SUM (cr11_1.cnt_report + cr11_2.cnt_report_2) as TOTAL
from biographical bio
LEFT JOIN (
SELECT cr.id, COUNT (*) AS cnt_report
FROM report cr
GROUP BY cr.id
) cr11_1 ON bio.id = cr11_1.id
LEFT JOIN (
SELECT cr.id2,
COUNT (*) AS cnt_report_2
FROM report cr
GROUP BY cr.id2
) cr11_2 ON bio.id = cr11_2.id2
GROUP BY bio.*
You can not do this:
sum(something, something_else)
but you can do this:
sum(something + something_else)
You can figure out how to implement that into your query. Remember that if you are selecting other fields along with an aggregate, you need a group by clause.

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