sql if null show 0 - mysql

In SQL how do you show 0 if record is null?
select sales_id, totalbuy, totalsell, totalbuy + totalsell as total from
(select sales_id, SUM(CASE WHEN side= 'buy' THEN 1 ELSE 0 END) AS totalbuy,
SUM(CASE WHEN side= 'sell' THEN 1 ELSE 0 END) AS totalsell
from car_orders
where sales_id in ('sales1', 'sales2', 'sales3', 'sales4')only
GROUP BY sales_id)q
order by total desc
limit 0, 10;
After car_orders I have tried inserting*(car_orders+ISNULL(car_orders,0)) but get an error.

Building from Sohnee's answer, here is the SQL I think you want to use:
SELECT
sales_id,
IFNULL(totalbuy, 0),
IFNULL(totalsell, 0),
IFNULL(totalbuy, 0) + IFNULL(totalsell, 0) as total
FROM
(
SELECT
sid as sales_id,
SUM(CASE WHEN side = 'buy' THEN 1 ELSE 0 END) AS totalbuy,
SUM(CASE WHEN side = 'sell' THEN 1 ELSE 0 END) AS totalsell
FROM
( SELECT 'sales1' as sid UNION SELECT 'sales2' UNION SELECT 'sales3' UNION SELECT 'sales4' ) mysalesids
LEFT OUTER JOIN car_orders
ON sales_id = sid
GROUP BY
sales_id
) q
ORDER BY total DESC
LIMIT 0, 10;
The key to the above is the "LEFT OUTER JOIN". If you can have the 'sales1', 'sales2', 'sales3' values in their own table, that would be preferable rather than having a sub-select.
Hope this helps,
john...

When you use +, both arguments must be of the same type. I can't tell from your question what car is, but I assume it isn't compatible with a 0.
It is better to use CONCAT in these cases.
CONCAT(car, IFNULL(car_orders, 0))
If car_orders is a table, it isn't valid here - you must use a column, i.e. car_orders.MyColumn
How To Use IFNULL
I don't think you can end up with a null here, given your query, buy you would use IFNULL like this:
SELECT
sales_id,
IFNULL(totalbuy, 0),
IFNULL(totalsell, 0),
IFNULL(totalbuy, 0) + IFNULL(totalsell, 0) as total
FROM
(
SELECT
sales_id,
SUM(CASE WHEN side = 'buy' THEN 1 ELSE 0 END) AS totalbuy,
SUM(CASE WHEN side = 'sell' THEN 1 ELSE 0 END) AS totalsell
FROM
car_orders
WHERE
sales_id in ('sales1', 'sales2', 'sales3', 'sales4')
GROUP BY
sales_id
) q
ORDER BY total DESC
LIMIT 0, 10;

Related

order by not working on alias column in mysql query with union all query

SELECT SUM(T1.approve_con) AS compl_rec,
SUM(T1.payout) AS payout,
SUM(T1.reversal) AS reversal,
T1.app_id,
T1.end_user,
T1.created
FROM (
(SELECT app_id,end_user,created,
approve_conversions AS `approve_con`,
'0' AS reversal,
payout AS payout
FROM app_end_users
WHERE publisher_id=1625
AND app_id=57)
UNION ALL
(SELECT opinongold_survey_response.app_id,
opinongold_survey_response.user_id AS end_user,
opinongold_survey_response.movement AS created,
(CASE WHEN opinongold_survey_response.survey_status= 'Completed' THEN 1 ELSE 0 END) AS `approve_con`,
(CASE WHEN opinongold_survey_response.survey_status= 'Rejected' THEN 1 ELSE 0 END) AS reversal,
(CASE WHEN opinongold_survey_response.survey_status= 'Completed' THEN payout ELSE 0 END) AS payout
FROM opinongold_survey_response
WHERE pub_id=1625
AND app_id=57)
) AS T1
GROUP BY T1.app_id,T1.end_user
ORDER BY `approve_con` DESC
LIMIT 0, 10
above is my mysql query order by is not working on approve_con, payout, reversal column
please let me where i am doing wrong in this query.

MySQL - join/group concat returning too many items

I've got a simple query which brings up wins, draws and losses in a head-to-head matches table.
SELECT
SUM(CASE WHEN score_w > score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN score_m > score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN score_w = score_m THEN 1 ELSE 0 END) AS draws
FROM 6dos7me3xn8
All is well. I get a single row, with the data I need as columns.
Now I want to also pull out a group concat'd list of the most recent three match dates. I tried:
SELECT
SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3) jn
...but the LIMIT is having no effect, seemingly - I get all of the dates group concat'd, not just 3.
I also tried removing the JOIN and replacing the GROUP_CONCAT with
GROUP_CONCAT((SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3)) AS recent
...but that errors with 'Subquery returns more than 1 row.'
I'm sure it's something simple, but what am I doing wrong?
If you are running MySQL 8.0, you can do this with window functions:
select
sum(score_w > score_m) as wins_w,
sum(score_m > score_w) as wins_m,
sum(score_w = score_m) as draws,
group_concat(case when rn <= 3 then date end) as recent
from (
select t.*, row_number() over(order by date desc) rn
from `6dos7me3xn8` t
) t
The subquery ranks records by descending date; we can then use that information in the outer query. Note that you don't need the case expressions: MySQL evaluates true/false conditions as 1/0 in numeric contet.
In earlier versions, the simpler approach is probably a row-limiting subquery:
select
sum(score_w > score_m) as wins_w,
sum(score_m > score_w) as wins_m,
sum(score_w = score_m) as draws,
(select group_concat(date) from (select date from `6dos7me3xn8` order by date desc limit 3) t) as recent
from `6dos7me3xn8`
You are doing a cross join. TO get the most recent three dates, you can use:
FROM (SELECT mn.*, DENSE_RANK() OVER (ORDER BY date desc) as seqnum
FROM 6dos7me3xn8 mn
) mn
WHERE seqnum <= 3
You have no ON clause to specify the relationship between the subquery and the table you're joining it to. So you get a full cross product.
You also need ORDER BY to make it return the 3 most recent dates, not any 3 dates.
SELECT
SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (
SELECT DISTINCT date
FROM 6dos7me3xn8
ORDER BY date DESC
LIMIT 3
) jn ON jn.date = mn.date

Count different values in a column, while doing total and group by different column values

We have a table with data from different nodes and one of the column will have status report as "compliant or non-compliant", sample data as below
I want to filter the table in such a way that if any of the checks on a node shows non compliant, it should be flagged as non-compliant and rest as compliant. Using below query i am able to do it
SELECT COUNT(*) AS total_nodes,
SUM(fully_compliant = 0) AS Non_compliant_nodes,
SUM(fully_compliant = 1) AS compliant_nodes
FROM (
SELECT Node, CASE WHEN SUM(Status = 'Compliant') = COUNT(*) THEN 1 ELSE 0 END AS fully_compliant
FROM your_table GROUP BY Node
)
Now, i want to group and split the result by dept as below, how can i achieve this
I think you're looking for this:
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
sum(case when 'Non-Compliant' then 1 else 0 end) as non_compliant_chk
from your_table
group by dept,
node
) v
group by dept;
With few modifications to what Brian suggested, I am able to get the desired result
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
COUNT(CASE WHEN Compliance-Status = 'Non-Compliant' THEN 1 END) 'non_compliant_chk'
from table WHERE DOR >= DATE(NOW()) - INTERVAL 7 DAY
group by Dept,
Node
) v
group by Dept;

Limit sql query and rank according to total

I have a sql query for my MYSQL DB and want to limit the results to only 10 sales people instead of 20. I have tried inserting their names inside the query but keep getting error. Also is it possible to rank according to total. The sql query I am using is:
select sales_id, totalbuy, totalsell, totalbuy + totalsell as total from
(select sales_id, SUM(CASE WHEN side= 'buy' THEN 1 ELSE 0 END) AS totalbuy,
SUM(CASE WHEN side= 'sell' THEN 1 ELSE 0 END) AS totalsell
from sales_id where sales_id='sales1', GROUP BY sales_id)q
where it says sales1 I have attempted to add the remaining 9 sales_ids' using a comma and single quotes but can't get it to work.
If you want certain sales_id only, use the "IN " clause.
if you wanna only the top 10 total, remove that line and use LIMIT
select sales_id, totalbuy, totalsell, totalbuy + totalsell as total from
(select owner_id, SUM(CASE WHEN side= 'buy' THEN 1 ELSE 0 END) AS totalbuy,
SUM(CASE WHEN side= 'sell' THEN 1 ELSE 0 END) AS totalsell
from sales_id
where sales_id in ('sales1', 'sales2', 'sales3', 'sales4')-- if you wanna certain sales_id only
GROUP BY sales_id)q
order by total desc
limit 0, 10;--top 10 by total (bigger first)

MySQL order rank as a column

I have a MySQL query that selects data from multiple tables and then orders the results based on some arbitrary criteria as below:
SELECT [columns] FROM (
SELECT *, COUNT(*) as `matches`
FROM [table1]
JOIN [table2] USING (id)
JOIN [table3] USING (id)
WHERE [criteria]
GROUP BY `id`
ORDER BY `matches` DESC
) AS `grouped`
ORDER BY (
(CASE WHEN [1st rank criteria] THEN 3 ELSE 0 END) +
(CASE WHEN [2nd rank criteria] THEN 2 ELSE 0 END) +
(CASE WHEN [3rd tank criteria] THEN 1 ELSE 0 END)
) DESC
LIMIT 100
This works fine, but my question is: can I have the ranking score displayed as a column? I've looked at trying to use variables, but I'm quite new to SQL so all this is a bit beyond me.
Sorry if this is an obvious question, but many thanks in advance for your time and assistance.
Try this:
SELECT [columns],
(
(CASE WHEN [1st rank criteria] THEN 3 ELSE 0 END) +
(CASE WHEN [2nd rank criteria] THEN 2 ELSE 0 END) +
(CASE WHEN [3rd tank criteria] THEN 1 ELSE 0 END)
) AS MyRank
FROM (
SELECT *, COUNT(*) as `matches`
FROM [table1]
JOIN [table2] USING (id)
JOIN [table3] USING (id)
WHERE [criteria]
GROUP BY `id`
ORDER BY `matches` DESC
) AS `grouped`
ORDER BY MyRank DESC
LIMIT 100;
put it in the select
((CASE WHEN [1st rank criteria] THEN 3 ELSE 0 END) +
(CASE WHEN [2nd rank criteria] THEN 2 ELSE 0 END) +
(CASE WHEN [3rd tank criteria] THEN 1 ELSE 0 END)) as ranking