Select count from multiple tables and group by - mysql

Help me!
$sql = SELECT `id`, `email`, `avatar`,`fullname`,
SUM(result) as sum_result,
SUM(total) as sum_total,
COUNT(rank) as `top_1` where `itq_exam_thread_test`.`rank` = 1,
COUNT(rank) as `top_2` where `itq_exam_thread_test`.`rank` = 2,
COUNT(rank) as `top_3` where `itq_exam_thread_test`.`rank` = 3
GROUP BY userid_created
ORDER BY sum_result DESC, sum_rate DESC
LIMIT 0, 100';
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'where itq_exam_thread_test.rank = 1,

WHERE is a clause for the entire query, not a modifier in the SELECT clause. What you want is conditional aggregation. In MySQL, doing the count is quite easy, because it treats boolean expressions as integers in a numeric context. So, you can just use SUM():
SELECT id, email, avatar, fullname, SUM(result) as sum_result,
SUM(total) as sum_total,
SUM(rank = 1) as top_1,
SUM(rank = 2) as top_2,
SUM(rank = 3) as top_3
FROM itq_exam_thread_test
GROUP BY userid_created
ORDER BY sum_result DESC
LIMIT 0, 100;
I removed sum_rate from the ORDER BY, because it is not defined.

Related

sql order by not working with decimal(18,6)

The SQL query with order by clause is not working properly.
Query:
select cast(actual_qty as decimal(18,2)) from `Bin`
where warehouse = `Warehouse`.name
order by actual_qty desc
Output of above query:
303.00
550.00
0.00
3.00
The type of actual_qty is decimal(18,6). I tried using cast function in order by, didn't work.
Any help is much appreciated!!
Update1:
Here's my full query that is being fired:
select `tabWarehouse`.name, CONCAT_WS(" : ", "Actual Qty", ifnull( ( select round(`tabBin`.actual_qty, 2) as qty
from `tabBin` where `tabBin`.warehouse = `tabWarehouse`.name
and `tabBin`.item_code = '30440'
order by qty desc), 0) ) as actual_qty
from `tabWarehouse` where `tabWarehouse`.`name` like '%%%%' and ifnull(`tabWarehouse`.company, '') in ('', 'TILE TEST') and `tabWarehouse`.is_group = 0.0
limit 0, 20
The output is still the same which is not really ordered by the qty in a descending manner.
Update 2:
This is how my code looks:
query = """select tw.name,
CONCAT_WS(" : ", "Actual Qty", ifnull(round(`tabBin`.actual_qty, 2), 0 ) actual_qty
from `tabWarehouse` tw left join `tabBin` tb
on tb.warehouse = tw.name {bin_conditions}
where
tw.`{key}` like {txt}
{fcond} {mcond}
order by ifnull(round(tb.actual_qty, 2), 0) desc
limit
{start}, {page_len}
""".format(
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),bin_conditions, ignore_permissions=True),
# sub_query=sub_query,
key=searchfield,
fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
mcond=get_match_cond(doctype),
start=start,
page_len=page_len,
txt=frappe.db.escape('%{0}%'.format(txt))
)
The cast in select doesn't change the type of the column -- and the order by is referring to the column in the table, not the expression in the select.
One option is to give it a new name and use that:
select cast(actual_qty as decimal(18,2)) as qty
from `Bin`
where warehouse = `Warehouse`.name
order by qty desc;
Or repeat the expression:
select cast(actual_qty as decimal(18,2)) as qty
from `Bin`
where warehouse = `Warehouse`.name
order by cast(actual_qty as decimal(18,2)) desc
There is no ORDER BY clause in your query.
The ORDER BY inside the correlated subquery is useless because that subquery will work only if it returns only 1 row and does not effect the final results.
Try this:
select tw.name,
CONCAT_WS(" : ", "Actual Qty", ifnull(round(tb.actual_qty, 2), 0)) actual_qty
from tabWarehouse tw left join tabBin tb
on tb.warehouse = tw.name and tb.item_code = '30440'
where tw.name like '%%%%'
and ifnull(tw.company, '') in ('', 'TILE SELECT')
and tw.is_group = 0.0
order by ifnull(round(tb.actual_qty, 2), 0) desc limit 0, 20
Also what is this condition:
`tabWarehouse`.`name` like '%%%%'

mysql sql error when using the row_number

This query is throwing error, it seems correct but i am getting an error
WITH Rows AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as [Row]
FROM users
WHERE 1=1
)
SELECT * FROM Rows
WHERE Row >= 1 and Row <= 10
error i am getting while running the above statement is:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Rows AS (SELECT *, ROW_NUMBER() OVER (ORDER BY userid asc)
FROM users
' at line 1
Your error is on Rows because MySQL does not recognize the CTE.
Then, MySQL also does not recognize [, so you want to use a more reasonable name. In MySQL 8+, that would be something like:
WITH Rows AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as seqnum
FROM users
)
SELECT *
FROM Rows
WHERE seqnum <= 10;
You don't need to compare to 1. That is definitional.
Of course, this, in turn, is overkill. The CTE is unnecessary:
SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as seqnum
FROM users
ORDER BY userid
LIMIT 10;
But this will still fail, because MySQL versions started recognizing CTEs and window functions in the same version.
So, you can just use variables:
SELECT u.*, (#rn := #rn + 1) as seqnum
FROM users u CROSS JOIN
(SELECT #rn := 0) params
ORDER BY userid
LIMIT 10;

Two select statments with union not working

i am trying to implement following query,
(SELECT
MAX(final_avg_total.`Provider Name`) AS `Hospital Name`,
final_avg_total.`DRG Definition`,
final_avg_total.`Provider Id`,
SUM(final_avg_total.avg_total_payments) AS avg_payments,
SUM(final_avg_total.avg_covered_charges) AS avg_covered,
(SUM(final_avg_total.avg_covered_charges) - SUM(final_avg_total.avg_total_payments)) / SUM(final_avg_total.avg_covered_charges) AS total_average,
1 - (SUM(final_avg_total.avg_covered_charges) - SUM(final_avg_total.avg_total_payments)) / SUM(final_avg_total.avg_covered_charges) AS total_percentage
FROM final_avg_total
GROUP BY final_avg_total.`Provider Id`
ORDER BY total_average DESC LIMIT 0,5)
Union
SELECT
MAX(final_avg_total.`Provider Name`) AS `Hospital Name`,
final_avg_total.`DRG Definition`,
final_avg_total.`Provider Id`,
SUM(final_avg_total.avg_total_payments) AS avg_payments,
SUM(final_avg_total.avg_covered_charges) AS avg_covered,
(SUM(final_avg_total.avg_covered_charges) - SUM(final_avg_total.avg_total_payments)) / SUM(final_avg_total.avg_covered_charges) AS total_average,
1 - (SUM(final_avg_total.avg_covered_charges) - SUM(final_avg_total.avg_total_payments)) / SUM(final_avg_total.avg_covered_charges) AS total_percentage
FROM final_avg_total
GROUP BY final_avg_total.`total_percentage`
ORDER BY total_average DESC LIMIT 0,5
actually both queries are almost same with only Group By is Differing, but i am getting this error.
5 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT
MAX(final_avg_total.`Provider Name`) AS `Hospital Name`,
fin'
It can be helpful to opt for a smaller problem, if possible.
See if you get the same results if you
CREATE OR REPLACE VIEW part_one AS ... ;
CREATE OR REPLACE VIEW part_two AS ... ;
and then
SELECT * FROM part_one
UNION
SELECT * FROM part_two;
Letting a database engine comprehend the work on it piece-wise has helped me in times past. Also can aid code maintenance.
If you get dupes, UNION ALL is another handy arrow in the quiver.
this is just a regular UNION with error
http://www.sqlfiddle.com/#!2/ec657/7
and this is the 'same' UNION without error
http://www.sqlfiddle.com/#!2/ec657/8
the only difference is the parenthesis in both case, please be sure to place parenthesis just after the UNION or remove it
...
ORDER BY total_average DESC LIMIT 0,5)
Union
(SELECT --ADDED PARENTHESIS
MAX(final_avg_total.`Provider Name`) AS `Hospital Name`,
...
ORDER BY total_average DESC LIMIT 0,5) --ADDED PARENTHESIS

Error Trying to Use Temporary Columns, mysql

I am getting this error,
#1054 - Unknown column 'finalResult' in 'field list'
when ever I run this mysql query
SELECT userID, pickID, nflp_picks.gameID, visitorID, visitorResult, homeID, homeResult,
IF (pickID=visitorID, visitorResult, homeResult) AS finalResult,
IF (finalResult="Winner", 1, 0) AS Win
FROM nflp_picks, nflp_schedule
WHERE nflp_picks.gameID = nflp_schedule.gameID
ORDER BY gameID, pickID, userID
LIMIT 0, 200
Can I not use temporary columns?
You can't refer to aliases in the same query, except in GROUP BY, ORDER BY, and HAVING clauses. You can use a subquery:
SELECT *, (finalResult = "Winner") AS Win
FROM (SELECT userID, pickID, nflp_picks.gameID, visitorID, visitorResult, homeID, homeResult,
IF (pickID=visitorID, visitorResult, homeResult) AS finalResult
FROM nflp_picks
JOIN nflp_schedule
ON nflp_picks.gameID = nflp_schedule.gameID
ORDER BY gameID, pickID, userID
LIMIT 0, 200) x

Invalid use of group function - MySQL

This error occurs while I run the select query, please advise.
Error No : 1111
Error : Invalid use of group function
Query:
SELECT cm.contactid, cm.firstname, cm.surname, cm.mobile, COUNT( * ) total
FROM sales_master as sm, contact_master as cm
WHERE sm.contactid = cm.contactid
AND cm.mobile != '' AND orderdate>='2012-12-18' AND orderdate<='2013-03-18'
GROUP BY sm.contactid
HAVING COUNT(*) >= 1
ORDER BY COUNT(*) DESC, cm.firstname ASC
Change your query like this. Use join instead of cartisian. If type of cm.orderdate is DAte than remove DATE() from the below query. And use alias total in GROUP BY and ORDER BY
instead of Count(*) .
SELECT
cm.contactid,
cm.firstname,
cm.surname,
cm.mobile,
COUNT(cm.contactid) total
FROM sales_master as sm
LEFT JOIN contact_master as cm
ON sm.contactid = cm.contactid
WHERE
AND cm.mobile != ''
AND DATE(cm.orderdate) >= '2012-12-18'
AND DATE(cm.orderdate) <= '2013-03-18'
GROUP BY cm.contactid
HAVING total >= 1
ORDER BY total DESC, cm.firstname ASC
There will be two reason:
1) Version compatibility Problem
2) Your query syntax is not ok,I am sending you the solution of second option.
For Version compatibility Problem you must go to the link mentioned by some one on
comment.
You have to use subquery concept for that.
Modify your query something like that:
SELECT sm.contactid ,cm.contactid as contactid , cm.firstname as firstname, cm.surname as surname , cm.mobile as mobile , COUNT( * ) total
FROM (
SELECT sm.contactid,contactid , firstname,surname ,mobile ,total
FROM sales_master as sm, contact_master as cm
WHERE sm.contactid = cm.contactid
AND cm.mobile != '' AND orderdate>='2012-12-18' AND orderdate<='2013-03-18'
GROUP BY sm.contactid
) q
GROUP BY sm.contactid HAVING COUNT(*) >= 1
ORDER BY COUNT(*) DESC, cm.firstname ASC
I am not sure that i made exact query or not but concept is some thing like that means
"Subquery"...