How to use cross join with left outer join? - mysql

I have to show list of employee who has claim for expense for the particular month, but am getting all employee list.
SELECT employee_id, expense_month, GROUP_CONCAT(CONCAT_WS('=', exp_type_text, monthly_exployee_expense))
FROM
(
SELECT tbl_employee.employee_id, expense_months.expense_month, tbl_expense_type.exp_type_id, tbl_expense_type.exp_type_text, SUM(expense_cost) AS monthly_exployee_expense
FROM tbl_employee
CROSS JOIN tbl_expense_type
CROSS JOIN
(
SELECT DISTINCT DATE_FORMAT(expense_date, '%Y%m') AS expense_month
FROM exp_tbl
) expense_months
LEFT OUTER JOIN exp_tbl
ON tbl_employee.employee_id = exp_tbl.employee_id
AND tbl_expense_type.exp_type_id = some_table.expense_type
AND expense_months.expense_month = DATE_FORMAT(exp_tbl.expense_date, '%Y%m')
GROUP BY tbl_employee.employee_id, expense_months.expense_month, tbl_expense_type.exp_type_id, tbl_expense_type.exp_type_text
) Sub1
GROUP BY employee_id, expense_month
this the query i had.. how to get only expense claimed employee list.
Example out put is:
3 Ramesh Kumar M 201402 Phone Expense=0=16,Consumable Purchase=0=11,Auto=0...
3 Ramesh Kumar M 201403 Consumable Purchase=0=11,Auto=0=6,2 wheeler=0=1,Lo...
3 Ramesh Kumar M 201404 Logistics/Transportation=0=18,Labour=0=13,Fuel=0=8...
3 Ramesh Kumar M 201405 Bus Travel=0=3,Office Vehicle=0=20,Others=0=15,Sta...
4 testexplevel1 201402 Others=0=15,Stay=0=10,Train Travel=0=5,Office Main...
4 testexplevel1 201403 Office Maintenance=0=17,Billable Purchase=0=12,Cal...
4 testexplevel1 201404 Call Taxi=0=7,4 wheeler=0=2,Guest House=0=19,Trans...
In that list not want all employee list. Only show ramesh data. Because that employee only has claimed.

Makes sense. You cross join all employees against all months and all expense types into a big cartesian product. Then you left join the actual expenses, so nothing gets excluded if there are no expenses.
So the quick fix would be to inner join the expenses. Doing so only gives you the employee-months for which an expense exists.
But doing so also allows you to remove the cross joins altogether and change it all to inner joins:
select
emp.employee_id,
DATE_FORMAT(ex.expense_date, '%Y%m'),
GROUP_CONCAT(CONCAT_WS('=', et.exp_type_text, ex.monthly_exployee_expense))
from
tbl_employee emp
inner join exp_tbl ex on ex.employee_id = emp.employee_id
inner join tbl_expense_type et on et.exp_type_id = ex.expense_type
group by
emp.employee_id,
DATE_FORMAT(ex.expense_date, '%Y%m')
Now, isn't that query much cleaner? :)

Related

How to add the tax and then multiply with the price in mysql

I am trying to add the tax and multiply the result with a total price.
Here are the tables
"Charge" Table
Charge_Type
Tax_type
charge type tax list
I want to calculate the tax and the multiply with the amount for each charge_id
I tried attempting this way:
SELECT `charge_id` AS "Charge ID", SUM( tt.percentage ) AS "Tax"
FROM charge c, charge_type ct, tax_type tt, charge_type_tax_list cttl
WHERE tt.tax_type_id = cttl.tax_type_id
GROUP BY c.charge_type_id, c.charge_id
LIMIT 0 , 30
You are using a join syntax that was made redundant more than twenty years ago. Whichever book or class or tutorial has been teaching you this outdated syntax, quit it. This syntax is prone to errors, as your own query plainly shows. Your query translated to proper joins is:
SELECT `charge_id` AS "Charge ID", SUM( tt.percentage ) AS "Tax"
FROM charge c
CROSS JOIN charge_type ct
CROSS JOIN tax_type tt
INNER JOIN charge_type_tax_list cttl ON tt.tax_type_id = cttl.tax_type_id
GROUP BY c.charge_type_id, c.charge_id
LIMIT 0 , 30
You are combining all charge records with all charge_type records and all tax_type records. 6 x 3 x 3 = 54 records in your example. This makes no sense. You would want to join only related records in the first place.
What you really want to do is join charges with their tax sum:
select
c.charge_id,
tax.tax_sum,
c.amount,
c.amount * (1 + coalesce(tax.tax_sum, 0)) as taxed_amount
from charge c
left join
(
select
cttl.charge_type_id,
sum(tt.percentage) as tax_sum
from charge_type_tax_list cttl
join tax_type tt on tt.tax_type_id = cttl.tax_type_id
group by cttl.charge_type_id
) tax on tax.charge_type_id = c.charge_type_id;
You could do an INNER JOIN between the tables and calculate the corresponding percentage's grouped by charge id. The query below should do the trick:
SELECT charge.charge_type_id, (SUM(percentage) + 1) * charge.amount AS total_tax
FROM charge INNER JOIN charge_type ON charge.charge_type_id = charge_type.charge_type_id
INNER JOIN charge_type_tax_list ON charge_type.id = charge_type_tax_list.charge_type_id
INNER JOIN tax_type ON charge_type_tax_list.tax_type_id = tax_type.tax_type_id GROUP BY charges.id;

Is this sql query correct?

Using table below
http://i.imgur.com/rIMgFZC.png
How do i display the names of toys that processed by Female Employees who are in level 3, level 4, and level 5 (not level 1 or 2) and a list of all toys’ name with stores’ postcode 10005. Write using union.
SELECT Toy_name
FROM Toy T
INNER JOIN hire_transaction H on T.toy_id = H.toy_id
INNER JOIN Employee E on H.E_id = E.E_id
WHERE E_Sex = ‘F’
AND E_Level between ‘3’ and ‘5’
UNION
SELECT Toy_name, Store_id
FROM Toy T, Store S
WHERE T.Store_ID IN(
SELECT Store_ID
FROM STORE S
WHERE Store_Postcode = ‘10005’);
this is my attempt. am i correct?
SELECT Toy_name
FROM Toy T
INNER JOIN hire_transaction H on T.toy_id = H.toy_id
INNER JOIN Employee E on H.E_id = E.E_id
WHERE E_Sex = 'F'
AND E_Level between 3 and 5
UNION
SELECT Toy_name
FROM Toy T
WHERE T.Store_ID IN(
SELECT Store_ID
FROM STORE S
WHERE Store_Postcode = '10005');
When using unions the distinct selects must have the same number and types of columns.
Removed the unnecessary implicit join in your second query.
You used the wrong quotation marks, inserted the single quotes.

SQL Query -- Student Weighted Grade Calculation

I am having trouble calculating students grades together to get their final grade.
I have the following tables
Students
----------------
stu_id
stu_fname
stu_lname
Grades
----------------
grade_id
grade_name
grade_type
grade_possible
StudentGrades
-----------------
stu_grade_id
grade_id
stu_id
grade_earned
GradeTypes
----------------
grade_type
grade_type_name
grade_weight
This is the query that I have been able to come up with
Select S.stu_fname, S.stu_lname, GT.grade_type_name,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S
INNER JOIN StudentGrade SG on SG.stu_id = S.stu_id
INNER JOIN Grade G on SG.grade_id = G.grade_id
INNER JOIN GradeType GT WHERE G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname, GT.grade_type_name;
I get the query report below
James | Fort | HW/QUIZ | 30.0
James | Fort | LogBook | 60.0
Robin | Hood | HW/QUIZ | 60.0
Robin | Hood | Logbook | 25.0
I want to be able to add both of James Forts grades together to get his final grade and the same for Robin Hood.
Any help is appreciated, I am stuck at this point. I am almost done. I have researched sub queries and need more help to narrow my search to get the answer.
Have you tried the following ?
SELECT results.stu_fname, results.stu_lname, sum(results.CalculatedGrade)
FROM(
SELECT S.stu_fname, S.stu_lname, GT.grade_type_name,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S
INNER JOIN StudentGrade SG on SG.stu_id = S.stu_id
INNER JOIN Grade G on SG.grade_id = G.grade_id
INNER JOIN GradeType GT WHERE G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname, GT.grade_type_name
)results
GROUP BY results.stu_fname, results.stu_lname;
Edit: added aliases thanks to AshReva's remark.
Well, just remove GT.grade_type_name from the select and group by. Does this do what you need?
Select S.stu_fname, S.stu_lname,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S INNER JOIN
StudentGrade SG
on SG.stu_id = S.stu_id INNER JOIN
Grade G
on SG.grade_id = G.grade_id INNER JOIN
GradeType GT
on G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname;

how to write the select statement in case statement

Let me know how to write select query in case statement.
select
ROW_NUMBER() OVER(Order by vendor.VendorName ) AS ID,
PH.PurchasingHeaderID as BILLNo,
PH.TotalPriceCompanyCurrency as Balance,
acc.AccountName as [Account_Name]
**Into #tempOpenVedorlist**
from PurchasingHeader PH
LEFT OUTER JOIN TransactionType Trans ON PH.TransactionTypeID =Trans.TransactionTypeID
LEFT OUTER JOIN Vendor vendor on PH.VendorID=vendor.VendorID
LEFT OUTER JOIN PaymentTerm PT on PT.PaymentTermID = vendor.PaymentTermID
LEFT OUTER JOIN PurchasingDetail PD on PD.PurchasingHeaderID = PH.PurchasingHeaderI
LEFT OUTER JOIN Account Acc on Acc.AccountID= PD.FinancialAccountID
where PH.TransactionTypeID=7
Group by vendor.VendorName,
PH.PurchasingHeaderID,PH.TotalPriceCompanyCurrency,acc.AccountName
I GOT THIS RESULT :
with this result: Here i have No : VB1003 two times but Account Name is different.
ID BILLNo Account_Name Balance
-------------------------------------------------------------
101 VB1000 Cash-Petty Cash 4000.00
102 VB1001 Accounts Receivable 5000.00
103 VB1003 Cash-PettyCash 6000.00
104 VB1003 Cash 6000.00
105 VB1004 UndepositedFunds 7000.00
Here i have to show ;
I need this result :
ID BILLNo Account_Name Balance
------------------------------------------------------
101 VB1000 Cash-PettyCash 4000.00
102 VB1001 AccountsReceivable 5000.00
103 VB1003 ---Multiple---- 6000.00
104 VB1004 UndepositedFunds 7000.00
For aboue result what i have did : i have taken all the data in temp table.
Am able show Multiple string for which has more than one No.
But unfortunatly am not able show Account Name for which has only one BILLNo.
select ROW_NUMBER() OVER(Order by BILLNo ) AS ID,
[BILLNo],
Balance,
CASE
WHEN count(BILLNo)>1 THEN 'Multipul'
WHEN count(BILLNo)<2 THEN **(Select Account_Name from #tempOpenVedorlist )**
End As [Financial_Account]
from #tempOpenVedorlist
Group By BILLNo,Balance
Let me know how can i get account name from temp table which is related to that BILLNo.
Remove the AccountName from the GROUP BY and put an aggregate on that.
SELECT ROW_NUMBER() OVER(Order by vendor.VendorName ) AS ID,
PH.PurchasingHeaderID as BILLNo,
PH.TotalPriceCompanyCurrency as Balance,
CASE WHEN MIN(acc.AccountName) IS NULL
THEN '----'
WHEN MIN(acc.AccountName) = MAX(acc.AccountName)
THEN MIN(acc.AccountName)
ELSE '--MULTIPLE--'
END as [Account_Name]
INTO #tempOpenVedorlist
FROM PurchasingHeader PH
LEFT OUTER JOIN TransactionType Trans
ON PH.TransactionTypeID =Trans.TransactionTypeID
LEFT OUTER JOIN Vendor vendor
ON PH.VendorID=vendor.VendorID
LEFT OUTER JOIN PaymentTerm PT
ON PT.PaymentTermID = vendor.PaymentTermID
LEFT OUTER JOIN PurchasingDetail PD
ON PD.PurchasingHeaderID = PH.PurchasingHeaderI
LEFT OUTER JOIN Account Acc
ON Acc.AccountID= PD.FinancialAccountID
WHERE PH.TransactionTypeID=7
GROUP BY vendor.VendorName,
PH.PurchasingHeaderID,
PH.TotalPriceCompanyCurrency

sql query implement two count in one

SELECT (select count(u.ag_code)
from table1 as u inner join table2 as tc
on u.industry_id=tc.tempcatid
where u.ag_code!=0) as agnt,
(select count(u.ag_code)
from table1 as u inner join table2 as tc
on u.industry_id=tc.tempcatid where u.ag_code=0),as dircus,
tc.catename from table1 as u inner join table2 as tc
where u.industry_id=tc.tempcatid
group by tc.tempcatid
this query have error
i need two count and category name in one query
this is the condition for count
ag_code!=0
ag_code=0
in table1 have column ag_code (this have 0 and nonzero value)
my result need like this
Full Texts
agent customer catename
11 3 Real Estate
15 1 Automobile
3 0 Medical
34 77 Business
1 45 Travel & Hotels
11 3 Construction & Engineering
SELECT tc.catename,
count(case when u.ag_code!=0 then 1 end) agnt,
count(case when u.ag_code =0 then 1 end) dircus
from table1 as u
inner join table2 as tc on u.industry_id=tc.tempcatid
group by tc.tempcatid, tc.catename
Hi There you might be able to use the below example to get back the result you require.
Select SUM(Inactive) Inactive ,SUM(Active) Active FROM
(
Select Count(t1.UserId) Inactive,0 Active
FROM
(select * from users where inactive=1) as t1
UNION
SELECT 0 Inactive,Count(t2.UserId) Active FROM
(select * from users where inactive=0) as t2
) as result