Oracle SQL Developer - Count function - sql

This is the output of a select * from table1, I have a doubt with count function... I want to count that NULL, in order to do that the proper option is to do this:
select count(*) from table1 where fecha_devolucion is null --> This gives me the proper answer counting 1 however if i do:
select count(fecha_devolucion)
from table1
where fecha_devolucion is null --> this returns 0, why? Isn't the same syntax?
What's the difference between choosing a specific field and * from a table?

From the documentation (http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions032.htm):
If you specify expr, then COUNT returns the number of rows where expr
is not null. ...
If you specify the asterisk (*), then this function returns all rows...
In other words, COUNT(fecha_devolucion) counts non-NULL values of that column. COUNT(*) counts the total number of rows, regardless of the values.

This is the another way how you can get the count :
SELECT SUM(NVL(fecha_devolucion,1)) FROM table1 WHERE fecha_devolucion IS NULL;

Let's compare the two queries:
select count(*)
from table1
where fecha_devolucion is null;
select count(fecha_devolucion)
from table1
where fecha_devolucion is null;
I think you misunderstand the count() function. This function counts the number of non-NULL values in its argument list. With a constant or *, it counts all rows.
So, the first counts all the matching rows. The second counts all the non-NULL values of fecha_devolucion. But there are no such values because of the where clause.
By the way, you can also do:
select sum(case fecha_devolucion is null then 1 else 0 end) as Nullfecha_devolucion
from table1;

Related

SQL select either table 1 or table 2

I have two following queries. How can I modify this into single query? The result should be true if either query returns data, and false otherwise:
select custId from customer where customerId=3425632456 and custPhone='5653663251';
select accountnumber from account where accountId=524526 and accountPhone='5653663251';
Here custPhone=accountPhone
I think that you want exists:
select case
when exists (select custId from customer where customerId=3425632456 and custPhone='5653663251')
then 1
when exists (select accountnumber from account where accountId=524526 and accountPhone='5653663251')
then 1
else 0
end res
from dual
This query always return a single row, with a single column called res. If any of the subqueries returns something, then res has value 1, else 0.
As a performance bonus for using case, the second subquery is not executed if the first succeeds (this is called short-circuit evaluation). If your queries are time consuming, this can be interesting; make sure to put the less expensive query first.
If you actually want to return the values, then that's different. One option is union all:
select custId from customer where customerId=3425632456 and custPhone='5653663251'
union all
select accountnumber from account where accountId=524526 and accountPhone='5653663251'
Note that, unlike the first query, this does not guarantee that only one row will be returned. Depending on your data, this could give any number of row, 0 included. You might need additional casting to align the datatypes.
You could do a FULL OUTER JOIN on the two tables and check for the count using CASE statement:
SELECT
CASE
WHEN COUNT(*) > 0
THEN 'TRUE'
ELSE 'FALSE'
END result,
FROM
customer c
FULL OUTER JOIN
account a
ON c.custPhone = a.accountPhone
WHERE c.customerId=3425632456
AND a.accountId=524526
AND c.custPhone='5653663251;
Try this
select
custId,
accountnumber
from customer c
left join account a
on c.custPhone = a.accountPhone
where customerId = 3425632456
;

Automatic Fetch one record

I am execute below query. there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record.
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between '01-Oct-2019' and '14-Oct-2019';
But dont use Group BY function.
there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record
That's not how aggregate queries work.
An aggregate query with no GROUP BY returns one row. The result is the aggregation applied to the filtered rows. Because you had no rows which matched your criteria the aggregated value is NULL. If you had used a COUNT() function instead you would have got zero.
So, if you really want an empty result set (zero rows) when there's no matching data you can use this trick:
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between date '2019-10-01' and date '2019-10-14'
having count(*) > 0
;
Incidentally, you should get into the habit of using date literals instead of relying on implicit data conversion.
Quick demonstration about what you need
with w0 as
(
select 1 x from dual union
select 2 from dual
), w1 as
(
select * from w0 where 1=2
)
select c1 from (
select sum(x) c1 from w1
)
where c1 is not null
Click here for demo
Try this query
select sum(null) c1 from dual where 1=2
No data due to 1=2 but one row result

Null query in postgreSQL

I am trying to find the number of rows in a table with a particular column value = NULL in PostgreSQL. This is my query:
SELECT count(*)
FROM database.table
WHERE place_id = 3 AND user = (NULL);
And I get the count as 0. But there a pretty number of rows matching the query. What am I doing wrong here?
You should use IS NULL:
Select count (*) from database.table where place_id = 3 and user IS NULL;
Do not write expression = NULL because NULL is not "equal to" NULL. (The null value represents an unknown value, and it is not known whether two unknown values are equal.) This behavior conforms to the SQL standard.
If the value NULL comes from a variable, you can use IS DISTINCT FROM or IS NOT DISTINCT FROM which can compare NULL values:
SELECT COUNT(*) from database.table
WHERE place_id = 3 and user IS NOT DISTINCT FROM NULL
This query will also work for other values, especially parameters. The query
SELECT COUNT(*) from database.table
WHERE place_id = 3 and user IS NOT DISTINCT FROM $1
will work for $1 = 'Tom' and even $1 = NULL.

Comparing date with the Result Set in Oracle

Below is my query which is going to Generate two rows for me after execution of the query.
SELECT *FROM ELP_COUNTRY,ELP_COUNTRY_Tax where
ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
This query is returning two rows and again from that rows there is a date named effective date. so again from those rows I want to get the Highest date.
Can anyone help me on this. I am new to Oracle
You could self-join the table with the effective date and evaluate against that by adding something like this: (note the joins may not be correct since I'm just guessing what table the effective date is in and how the tables are related)
and elp_country.effective_date = (select max(e2.effective_date) from elp_country e2 where e2.country_id = elp_country.country_id and elp_country.description = 'Brasil')
Or if it's just a grouping thing you're trying to do then your select would be something like this:
SELECT max(effective_date), column2, column3
FROM ELP_COUNTRY,
ELP_COUNTRY_Tax
where ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and
GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
group by column2, column3;
You could use the rank function, and wrap that with a "select *" and a where clause predicate filtering the rank of 1, like so:
SELECT * FROM (
SELECT
c.*,
ct.*,
rank() over (order by ct.effective_date) as eff_date_rnk
FROM
ELP_COUNTRY c,
ELP_COUNTRY_Tax ct
WHERE
ELP_COUNTRY.COUNTRY_ID = Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil'
and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
) t
WHERE t.eff_date_rnk = 1;

Compare sums of two columns in sql

I have two tables with a column named no_id, I want to test that the values in both columns on the tables are the same.
So I´m trying to sum the values of both columns and compare the result.
SELECT
CASE
WHEN SUM (cast(a.no_id as bigint)) = SUM(cast(b.no_id as bigint)) THEN 'YES'
ELSE 'NO'
END as no_id
FROM table_a as a
,table_b as b
The result of the query is NO, but when I select each sum:
SELECT
SUM (cast(a.no_id as bigint)),
SUM(cast(b.no_id as bigint))
FROM table_a as a
,table_b as b
I got two nulls, one in each column. Instead of the sums of the columns.
I have to do this with other twenty columns of both tables.
no_id is a varchar(16) in both tables.
------UPDATE------
no_id only contains numeric strings,
I did the next query to ensure that null would be treated as 0:
SELECT
SUM(cast(ISNULL(a.no_id,0) as bigint)),
SUM(cast(ISNULL(b.no_id,0) as bigint))
FROM table_a as a
,table_b as b
But I keep getting the same result.
If I select the result from just one table, it works, I get the result of the sum:
SELECT
SUM(cast(ISNULL(a.no_id,0) as bigint))
FROM table_a as a
Then, why it doesn't work with both tables?
As I said in the comments:
Don't use the comma(,) operator in the FROM clause, it's been obsolete for over twenty years, use the JOIN keyword syntax instead. Because if you did you would know that ...
You are CROSS JOIN-ing your tables which is very bad and logically wrong 99% of the time. You need to use column subqueries instead.
Like this:
SELECT
CASE
WHEN (SELECT SUM(cast(no_id as bigint)) FROM table_a)
= (SELECT SUM(cast(no_id as bigint)) FROM table_b) THEN 'YES'
ELSE 'NO'
END as no_id
The problem is you don't say how table_a and table_b are related, so every row in table_a is paired with every row in table_b if either table has even one null value, then the total sum will be null.
If you just want the SUMS in both tables to match, then I;m not sure SUM is the best indicator. If table A had the values 1 and 4, and table b had 2 and 3, then the SUM would match but obviously the values are different.