Subtract the sum of one column from another table's column - mysql

What I have tried:
SELECT requestformtbl.employee_name, requestformtbl.request_type, requestformtbl.total_day,
requestformtbl.request_status, requestformtbl.admin_remark, requestformtbl.confirmed_by, requestformtbl.date_confirmed, requesttbl.max_allotment,
(requesttbl.max_allotment - sum(requestformtbl.total_day)) as Available from requestformtbl inner join requesttbl on
requestformtbl.request_type = requesttbl.request_type;
error: Column 'requestformtbl.employee_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If requestttbl.request_type="Vacation Leave" has requesttbl.max_allotment=20,
when a new entry in requestformtbl is inserted with requestformtbl.request_type="Vacation Leave" and requestformtbl.total_day=5
I want to get the remaining available leave

You can get the results you want without using a GROUP BY by using a correlated subquery to get the sum of the employees used days:
SELECT rft.employee_name,
rft.request_type,
rft.total_day,
rft.request_status,
rft.admin_remark,
rft.confirmed_by,
rft.date_confirmed,
rt.max_allotment,
rt.max_allotment - (select sum(total_day)
from requestformtbl rft2
where rft2.employee_name = rft.employee_name) as Available
from requestformtbl rft
inner join requesttbl rt on rft.request_type = rt.request_type;
Note I've used table aliases to make the query more readable.

Related

MySql, use group by with a WHERE clause

I want to add a WHERE clause to my statement, but the problem is,
when I add the WHERE clause, I get an error "Invalid use of group function".
I also tried to replace the WHERE clause and write the condition into the
JOIN .. ON part, but the error is still there.
I want to add the condition so that only the rows " SUM(res.ReservationID) = 2" are returned.
-- works but we only want to get the rows in which the SUM = 2
SELECT ctr.ID, ctr.LastName, ctr.FirstName, SUM(res.ReservationID) as ReservierteSitze
FROM customer as ctr
INNER JOIN reservation AS res ON ctr.ID = res.CustomerID
Group by ctr.ID;
SELECT ctr.ID, ctr.LastName, ctr.FirstName, SUM(res.ReservationID) as ReservierteSitze
FROM customer as ctr
INNER JOIN reservation AS res ON ctr.ID = res.CustomerID
Group by ctr.ID
HAVING ReservierteSitze = 2;
The HAVING clause is like a where clause for the GROUP BY (applies to the groupings)
You can still have a WHERE clause before the GROUP BY clause, but that only applies to the individual rows before the grouping.
having(Aggregation function condition processing)

count records is not giving the right number

When I type the following query
SELECT
COUNT(*) AS COUNT
FROM
OP_table OP
WHERE
OP.TARGET_ID= 4330000000000369;
I get a count of 55
When I try to use it in a join
SELECT
TS.TARGET_ID, T.TARGET_NAME, T.TARGET_PUBLIC_NAME, count( DISTINCT OP.OP_ID) AS OP_COUNT
FROM
TS_table TS
INNER jOIN
T_table T
ON
T.TARGET_ID = TS.TARGET_ID
OUTER JOIN
OP_TABLE OP
ON
OP.TARGET_ID = T.TARGET_ID
WHERE
TS.TARGET_SERVICE_ID = number
Then I get
TARGET_ID, TARGET_NAME, TARGET_PUBLIC_NAME, OP_COUNT
number, target name, Ebook Central History 33781
with an count of 33781. I want to use the 2nd functions structure but get the right count of 55
for some reason it's getting the count of the Target_id's instead of Target_service ID's
also I noticed if I type the following
SELECT
COUNT(*) AS COUNT
FROM
KB_OBJECT_PORTFOLIOS OP
WHERE
OP.TARGET_ID=4330000000000383;
where that number corresponds will produce the result 33781.
somewhere within the joining it's getting rid of the target ID of 4330000000000369 and using a different target ID 4330000000000383
Ok, I get mixed up from the stupid column names OP.target_ID = TS.target_service_id and not TS.target_ID...

Using results of one query into the next with unlike column names

My Platform is MySql
I have two queries that I need to combine, using the first query as a type of filter for the second query.
Query 1:
SELECT * FROM INVENTORY
WHERE INV_ID = 1
AND FSCL_YR = 2017
From this query we will get results back that includes a column named STR_NBR.
Which we then want to use in the second query as 'If the store number appears in the first query, give me the results where it shows in the second'. The second query tables use the column name SND_LOC_NBR instead of STR_NBR.
Query 2:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_NBR = B.XFER_NBR
AND A.XFER_STAT_IND IN ('S','C')
AND (where the SND_LOC_NBR needs to match STR_NBRs found from Query 1)
Try this:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_STAT_IND IN ('S','C')
AND SND_LOC_NBR IN
(SELECT STR_NBR FROM INVENTORY
WHERE INV_ID = 1 AND FSCL_YR = 2017 )

In sql server 2008

select tblProductMaster.*,AVG(tblReviewMaster.Rating) from tblProductMaster
left join tblReviewMaster
on tblProductMaster.ProductID = tblReviewMaster.ProductID
Group By tblProductMaster.ProductID
This query is returning an error:
Column 'tblReviewMaster.ReviewID' is invalid in the select list because it is not contained in either an aggregate function or the
GROUP BY clause.
It is not allowing me to have any column with AVG function... if I write
select AVG(tblReviewMaster.Rating) from tblProductMaster ...
then it works fine
So what to do to get product details from tblProductMaster also?
Error message says "Column 'tblReviewMaster.ReviewID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
This means all the columns other than column in aggregate functions(AVG) should be a part of Group By Clause. So if * means (Column 1, Column 2....etc) so all of these columns must be present in GroupBy clause.
So your query would be
select tblProductMaster.*,AVG(tblReviewMaster.Rating) from tblProductMaster
left join tblReviewMaster
on tblProductMaster.ProductID = tblReviewMaster.ProductID
Group By tblProductMaster.*
By *, I mean write all columns that represent *. * won't work here.
Please find more details on MSDN

Counting the number min records within groups

I'm building a report for a database where I need to determine the number of "first scans" grouping by company, job, and date.
The scan table can contain multiple scans for the same item, however I only want to include the original scan in my COUNT, which can only be identified as being the scan with the earliest date that matches a particular item.
My first attempt at this was:
SELECT
_item_detail.job_id,
_item_group.group_id,
_scan.company_id,
DATE(scan_date_time) as scan_date,
COUNT(1)
FROM _scan
INNER JOIN _item_detail ON _item_detail.company_id = _scan.company_id
AND
_item_detail.serial_number = _scan.serial_number
INNER JOIN _item_group ON _item_group.group_id = _item_detail.group_id
WHERE _item_detail.job_id = '0326FCM' AND _scan.company_id = '152345' AND _item_group.group_id = 13
GROUP BY
_item_detail.job_id,
_item_group.group_id,
_scan.company_id, scan_date -- first_scan_count
HAVING min(scan_date_time);
This is giving me incorrect results, though (about 3x too many). I am assuming it's because the MIN record is being recalculated for each date, so if the min was found on day 1, it may also be found on day 3 and counted again.
How can I modify my query to achieve the desired results?
Something similar to this should work... I'm not completely sure of how your tables are laid out or how the data relates them together, but this is the general idea:
SELECT
_item_detail.job_id,
_item_group.group_id,
_scan.company_id,
DATE(scan_date_time) as scan_date,
COUNT(1)
FROM
_scan s1
INNER JOIN _item_detail
ON _item_detail.company_id = s1.company_id
AND _item_detail.serial_number = s1.serial_number
AND _item_detail.job_id = '0326FCM'
INNER JOIN _item_group
ON _item_group.group_id = _item_detail.group_id
AND _item_group.group_id = 13
WHERE
s1.company_id = '152345'
AND s1.scan_date_time = (
SELECT MIN(s2.scan_date_time)
FROM _scan s2
WHERE
s2.company_id = s1.company_id
AND s2.serial_number = s1.serial_number
)
GROUP BY
_item_detail.job_id,
_item_group.group_id,
s1.company_id
I don't quite follow your query, but based on the description of the problem, I'd say create a subquery that gives the min scan date for for each item, group by items, the perform your outer select on that.