Using SUM so that NULL in columns make sum NULL - mysql

I have a a table with a column groups INTEGER NULL. It has values
groups
5
7
<NULL>
If I do a select sum(groups) form table_name
I would get 12. How can I get null, when the column being summed has a null.

One option:
CASE WHEN COUNT(*) = COUNT(groups) THEN SUM(groups) ELSE NULL END

select
case when exists (select groups from table where groups is null) then null
else select sum(groups) from table
end as grp_sum

Related

Difference Between Distinct Count() and Count(Distinct)

I have a Table Like so
user_id
status
1
true
1
true
2
false
2
true
Im Trying to Find the distinct count user_id where They are true and where they are false.
the query i have now is
SELECT
COUNT( DISTINCT CASE WHEN `status` = 'true' THEN 1 END ) AS `trues`,
COUNT( DISTINCT CASE WHEN `status` = 'false' THEN 1 END ) AS `false`,
FROM table
What is the difference between just removing Distinct from count and doing
SELECT DISTINCT
COUNT( CASE WHEN `status` = 'true' THEN 1 END ) AS `trues`,
COUNT( CASE WHEN `status` = 'false' THEN 1 END ) AS `false`,
FROM table
From the MySQL docs...
count
Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement.
count(distinct)
Returns a count of the number of rows with different non-NULL expr values.
For example, if you have 1, 1, 1, 2, 3, null count will count 1,1,1,2,3 for 5 and count(distinct) will count 1,2,3 for 3.
select distinct
DISTINCT specifies removal of duplicate rows from the result set.
The key difference between select distinct count() and select count(distinct) is with select count(distinct) the distinct filter happens while counting, with select distinct count() the distinct filter happens after counting.
SELECT
COUNT( DISTINCT CASE WHEN `status` = 'true' THEN 1 END ) AS `trues`,
COUNT( DISTINCT CASE WHEN `status` = 'false' THEN 1 END ) AS `false`
FROM table;
This will always be 1 or 0.
The case statements will always result in 1 or null, so the results can only be something like 1,1,null,1,null. There's only 1 distinct non-null value to count, so the result is 1. If there's no matches it's null, null, null, there's no distinct non-null values so the result is 0.
SELECT DISTINCT
COUNT( CASE WHEN `status` = 'true' THEN 1 END ) AS `trues`,
COUNT( CASE WHEN `status` = 'false' THEN 1 END ) AS `false`,
FROM table
Here, because there is a single row, the distinct has no effect; there's only one row and it's always going to be distinct.
But if there were multiple rows, perhaps because there's a group by, it would only return those results which are distinct. For example, let's say without the distinct we get...
trues false
------------
1 1
1 1
1 2
2 2
2 2
Then select distinct will only return those rows which are distinct.
trues false
------------
1 1
1 2
2 2
Try it.

Select records from table where a given column value has no non-null values in another column

In this simple table example:
ID SUBID
1000 NULL
1000 NULL
1000 1
1000 NULL
1001 NULL
1001 NULL
I would like my query to return an ID of 1001 only, because all 1001 IDs have NULL in SUBID. 1000 should be excluded, because at least one 1000 ID also has a non-NULL in SUBID.
So something like (convert my plain English to SQL):
select distinct id from table where all records with that id have NULL in subid
You could use a NOT IN the subid where is null
select distinct id
from table
where id NOT IN (
select distinct id from table where subid is null
)
Use a GROUP BY query and check that all SUBID entries are NULL using the BIT_AND() aggregate function:
select ID
from myTable
group by ID
having bit_and(SUBID is null)
Demo: https://www.db-fiddle.com/f/8dnfHV6VVVu7dvoZarTjdp/0
You can also replace the HAVING clause by
having count(SUBID) = 0
since COUNT() will ignore all NULL entries.
Demo: https://www.db-fiddle.com/f/t3FrL7zUAwGqqWDS4dQUg9/0
This version should work for any major RDBMS.
Or
having max(SUBID) is null
This works with most aggregate functions, since they will return NULL, if all entries are NULL. (COUNT() is an exception.)
However - MAX() or MIN() might be the fastest, if you have an index on (ID, SUBID).
You could use a NOT EXISTS clause to check for ID values which have a non-NULL subid value and exclude them from your result:
SELECT DISTINCT m1.ID
FROM myTable m1
WHERE NOT EXISTS (SELECT *
FROM myTable m2
WHERE m2.ID = m1.ID AND m2.subID IS NOT NULL)
Alternatively, you could count the rows associated with the ID value and also count the number of NULL subid values associated with that ID, and see if they are the same:
SELECT ID
FROM myTable m1
GROUP BY ID
HAVING COUNT(*) = SUM(subid IS NULL)
Output:
1001
Demo on dbfiddle

Insert empty row after group

I have a table that contains transaction data. The rows with the same 'group_id' are a part of the same transaction. I am running the following SQL query to show all the transactions:
SELECT * FROM transactions
When I run this query I get as expected a list of all the transactions. But this large list makes it difficult to seperate the data with a different group_id from the other data.
For that reason I want to add an empty row at the end of the group_id, so I get:
1
1
(empty row)
2
2
2
instead of:
1
1
2
2
2
Can someone help me with this?
Here is my database:
http://sqlfiddle.com/#!9/b9bf79/1
I do not suggest you do this at all but if you just want to separate two groups you could do this:
SELECT * FROM transactions WHERE group_id = 1
UNION ALL
(SELECT '','','','','','')
UNION ALL
SELECT * FROM transactions WHERE group_id = 2
Obviously this can added to if there are more group ids in the future but it is not a general purpose solution you are really better off dealing with appearance issues like this in application code.
you can use (abuse) rollup.
SELECT *
FROM transactions
group by group_id, id
with rollup
having group_id is not null
this will insert a row with id set to null after each group_id.
mysql will also sort by group_id because of the group by.
The group by id` makes sure that all rows are shown (your schema does not show it, but I assume id is unique? Otherwise you need to add other fields)
However only id will be null in the extra rows. The other columns repeat the value above.
You can filter them like this:
SELECT
id,
case id is not null when true then date else null end as date,
case id is not null when true then group_id else null end as group_id
-- ....
FROM transactions
group by group_id, id
with rollup
having group_id is not null
Alternatively:
select * from
(SELECT *
FROM transactions
union all
select distinct null, null, group_id, null, null,null from transactions
) as t
order by 3,1
but null values are sorted first, so the "gap" is in front of each section

mysql return null if such row exists otherwise return data

Hi Is there any option in mysql query to return NULL is there is no such row exists in database otherwise return the row data. Here is my query
SELECT DISTINCT estimateResourceMthObj
FROM EstimateResourceMth estimateResourceMthObj
WHERE estimateResourceMthObj.estimateResource.id IN
(
SELECT estimateResourceObj.id
FROM EstimateResource estimateResourceObj
WHERE estimateResourceObj.estimateSub.id = 7
)
AND estimateResourceMthObj.monthOrder >= 0
AND estimateResourceMthObj.monthOrder < 7;
I need to return the result of this query null if there is no such row exists otherwise i need to select that row. Is it possible to retrieve this in a single query?
As a tricky solution you can add UNION SELECT NULL LIMIT 0,1 to the end if you expect only one row, as you specified. So the result will always have one value - NULL if there are no matches in table and estimateResourceMthObj if there are.
SELECT DISTINCT estimateResourceMthObj
FROM EstimateResourceMth estimateResourceMthObj
WHERE estimateResourceMthObj.estimateResource.id IN
(
SELECT estimateResourceObj.id
FROM EstimateResource estimateResourceObj
WHERE estimateResourceObj.estimateSub.id = 7
)
AND estimateResourceMthObj.monthOrder >= 0
AND estimateResourceMthObj.monthOrder < 7
UNION
SELECT NULL
LIMIT 0,1;

get row count in single query in mysql

I have a table in that I want to get the rowcount of records in each column. where column1 is not null column2 is not null column3 is notnull and uID='2'
if the record is like
uid C1 C2 C3
2 Null 3 3
2 2 2 Null
the count here is C1=1, c2=2,c3=1 How can I do this in one query
COUNT(colname) should ignore NULL values in the aggregate, so the query should actually be simple. Note that COUNT(*) behaves differently, and does not ignore NULL rows.
SELECT COUNT(C1), COUNT(C2), COUNT(C3) FROM table WHERE uid=2
More information on the NULL aggregate behaviors is found here in the docs.
SELECT COUNT(C1), COUNT(C2), COUNT(C3)
FROM YourTable
WHERE uID = 2
GROUP BY uID
SELECT COUNT(C1), COUNT(C2), COUNT(C3)
FROM Mytable
WHERE uid=2
By default, it won't count NULL value.
select count(C1), count(C2), count(C3) from table