sql COALESCE result (12300.4567) to 12,300 - mysql

How to select COALESCE result to format( , 0)
my query is
SELECT (COALESCE((SELECT SUM(`invoices`.`paid_amount`) FROM `invoices`
WHERE DATE(`invoices`.`date`)=CURDATE()),0) +
COALESCE((SELECT SUM(`other_incomes`.`other_income_amount`) FROM `other_incomes`
WHERE DATE(`other_incomes`.`date`)=CURDATE()),0))
AS total
FROM
....

Primarily, COALESCE doesn't change the formatting. It only returns the first non-null value passed to it.
Also, instead of trying to join or do two different queries and adding, and handling all the sums and coalesces separately (not to mention the rounding), I would probably UNION all the relevant results together, then handle the coalesce/sum/round all at the end.
Try this:
SELECT round(sum(coalesce(amt, 0)), 0) as total
FROM (
SELECT paid_amount as amt
FROM invoices i
WHERE date(i.date) = CURDATE()
union all
SELECT other_income_amount
FROM other_incomes o
WHERE date(o.date) = CURDATE()
) z
Here I COALESCE first, to make nulls be 0 instead. I wrap that in a SUM to add up the values, and finally a ROUND to get the format. It was unclear from the question is you wanted to ROUND or FLOOR. If you are looking to get it with that comma, use FORMAT. Here's the mySQL documentation for that. You didn't specify your SQL flavor.
https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_format
Additionally, you should include your sql platform and version, the create statements for your tables, along with some insert statements that will provide sample data, along with the results you are looking for. It will help people answer your question. If you can include a fiddle, like https://dbfiddle.uk/, that would be nice.

Related

SQL Query - Select a value, then use it again in following statements

I've tried looking it up, and while I think this should be possible I can't seem to find the answer I need anywhere.
I need to lookup a date from one table, then store it for use in a following query.
Below is statements that should work, with my setting the variable (which I know won't work, but I'm unsure the best way to do/show it otherwise - bar maybe querying it twice inside the if statement.)
I'm then wanting to in the latter statement, use either the date given in the second query, or if the date from the first query (that I'm thinking to set as a variable) is newer, use that instead.
startDateVariable = (SELECT `userID`, `startDate`
FROM `empDetails`
WHERE `userID` = 1);
SELECT `userID`, SUM(`weeksGROSS`) AS yearGROSS
FROM `PAYSLIP`
WHERE `date` <= "2021-11-15"
AND `date` >= IF( "2020-11-15" > startDateVariable , "2020-11-15" , startDateVariable )
AND `userID` IN ( 1 )
GROUP BY `userID`
Naturally all dates given in the query ("2021-11-15" etc) would be inserted dynamically in the prepared statement.
Now while I've set the userID IN to just query 1, it'd be ideal if I can lookup multiple users this way at once, though I can accept that I may need to make an individual query per user doing it this way.
Much appreciated!
So turns I was going about this the wrong way, looks like the best way to do this or something similar is by using SQL JOIN
This allows you to query the tables as if they are one.
I also realised rather then using an IF, i could simply make sure i was looking up newer or equal to both the date given and the start date.
Below is working as required. And allows lookup of multiple users at once as wanted.
SELECT PAYSLIP.userID, employeeDetails.startDate, SUM(PAYSLIP.weeksGROSS) AS yearGROSS
FROM PAYSLIP
INNER JOIN employeeDetails ON employeeDetails.userID=PAYSLIP.userID
WHERE PAYSLIP.date <= "2021-11-15"
AND PAYSLIP.date >= "2020-11-15"
AND PAYSLIP.date >= employeeDetails.startDate
AND PAYSLIP.userID IN ( 1,2,8 )
GROUP BY PAYSLIP.userID
See here for more usage examples: https://www.w3schools.com/sql/sql_join.asp
However along the lines of my particular question, it's possible to store variables. I.E.
SET #myvar= 'Example showing how to declare variable';
Then use it in the SQL statement by using
#myvar where you want the variable to go.

SQL Select Max of Columns Where Date is Not Null

I currently am using this query to select some data:
SELECT DISTINCT a.code AS code, name, max(scen.Is3D) AS Is3D FROM locations LEFT JOIN .... The scen table has columns Is3D and Date. I only want to select the max of items where the date IS NOT NULL. I tried max(scen.Is3D WHERE scen.Date IS NOT NULL), but that didn't work. I cannot change anything after the FROM in my query, so I need that filtering to be done in the MAX, if possible. I am using MySQL 5.7.
You can use:
MAX(CASE WHEN scen.date IS NOT NULL THEN scen.Is3D END) AS Is3D
The CASE expression returns NULL when none of the WHEN conditions is met, but MAX() ignores null values, so this will just return the max of the Is3D columns in the selected rows.
So if we can't change anything after the FROM, then we cannot get a perfect solution here. Since you are SELECTing out the NULL values. One thing that we can try if we can only modify the final output is this.
SELECT MAX(ISNULL(scen.Date,0))...
This will replace all the NULLs with 0, but it would help to know exactly what you are trying to do. Why are you so convinced that the query itself cannot be modified in any way?
The other solution would be to put the whole query in another wrapper.
That would look like:
SELECT *
FROM (
[your whole query here]
) AS inner
WHERE inner.Date IS NOT NULL

SQL Assign "co-efficients" to query conditions and use them to sort result

I saw a query once that assigned some kind of ranking to query conditions, I can't remember it now.
They way I understood it, i think variable names (s1,s2,...) were assigned to each of the conditions with a coefficient to give them different "weights" then the sum of the variables was used to sort the result.
It looked something like this:
SELECT
*
FROM
table_name
WHERE condition1='value1' as (s1*3)
OR condition2='value2' as (s2*2)
OR condition3='value3' as (s3*1)
ORDER BY (s1+s2+s3)
So, the different numbers sort of give the conditions varying degrees of importance in the ORDER, makes it perfect for doing a related product/post search.
Please, does anyone know the right structure for this query?
In MySQL, you would define the aliases in the SELECT clause and then use them in the ORDER BY. For instance:
SELECT t.*, (condition1 = 'value1') as s1,
(condition2 = 'value2') as s2, (condition3 = 'value3') as s3
FROM table t
ORDER BY (s1*3 + s2*2 + s3*1);

Table statistics (aka row count) over time

i'm preparing a presentation about one of our apps and was asking myself the following question: "based on the data stored in our database, how much growth have happend over the last couple of years?"
so i'd like to basically show in one output/graph, how much data we're storing since beginning of the project.
my current query looks like this:
SELECT DATE_FORMAT(created,'%y-%m') AS label, COUNT(id) FROM table GROUP BY label ORDER BY label;
the example output would be:
11-03: 5
11-04: 200
11-05: 300
unfortunately, this query is missing the accumulation. i would like to receive the following result:
11-03: 5
11-04: 205 (200 + 5)
11-05: 505 (200 + 5 + 300)
is there any way to solve this problem in mysql without the need of having to call the query in a php-loop?
Yes, there's a way to do that. One approach uses MySQL user-defined variables (and behavior that is not guaranteed)
SELECT s.label
, s.cnt
, #tot := #tot + s.cnt AS running_subtotal
FROM ( SELECT DATE_FORMAT(t.created,'%y-%m') AS `label`
, COUNT(t.id) AS cnt
FROM articles t
GROUP BY `label`
ORDER BY `label`
) s
CROSS
JOIN ( SELECT #tot := 0 ) i
Let's unpack that a bit.
The inline view aliased as s returns the same resultset as your original query.
The inline view aliased as i returns a single row. We don't really care what it returns (except that we need it to return exactly one row because of the JOIN operation); what we care about is the side effect, a value of zero gets assigned to the #tot user variable.
Since MySQL materializes the inline view as a derived table, before the outer query runs, that variable gets initialized before the outer query runs.
For each row processed by the outer query, the value of cnt is added to #tot.
The return of s.cnt in the SELECT list is entirely optional, it's just there as a demonstration.
N.B. The MySQL reference manual specifically states that this behavior of user-defined variables is not guaranteed.

how to select and set value as 0 even if there is no value or data stored in database

Is there any select query that set value as 0 even if it is empty or no record stored in database?
Because I am trying to subtract values from two different tables. But the problem is that I cant subtract the the tables if one of them is no data stored.
Here is my code. This code can subtract if both tables have value.
SELECT category,(SELECT SUM(s.total)-SUM(r.total)
FROM rsales AS s WHERE r.pcode=s.pcode
) as total,
r.pcode
FROM rreturn AS r
GROUP BY r.pcode;
Use IFNULL or COALESCE:
SELECT IFNULL(SUM(s.total), 0)
SELECT COALESCE(SUM(s.total), 0)
If expr1 is not NULL, IFNULL() returns expr1; otherwise it returns expr2.
IFNULL() returns a numeric or string value, depending on the context in which it is used.
something like this should work
SUM(IF(s.total, s.total, 0))
OR
SUM(IFNULL(s.total), 0))
The syntax you're using is both confusing and error prone. I would go for something simpler like this:
SELECT category, SUM(s.total) - SUM(r.total) total
FROM rsales s
LEFT JOIN rreturn r USING (pcode)
GROUP BY s.pcode;
This assumes rreturn may not have records for each pcode.