Null query in postgreSQL - sql

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.

Related

Calculate field with value based on select statement

I currently have a select statement which returns Customer Numbers that are primary.
What I would like to do for those returned, I would like to have another column that is for customerRole. For customerRole the value should be either primary or secondary.
My current select statement is bringing those that are primary and based on that select statement. I would like to have a customerRole column that shows these as primary. Then I would like to use this same column with my other select statement to show those that are secondary. When they are ran together I would like to see something like:
accountNumber: 1234455 CustomerRole: Primary
AccountNumber: 3245454 CustomerRole: Secondary
Does anyone know how I can accomplish this? Here is my select to get primary numbers:
SELECT
F.CustomerNumber
FROM ods.CustomerFact F
JOIN ods.holderDim AD
ON F.HolderRowNumber = AD.HolderRowNumber
JOIN ods.holderOwesDim B
ON F.PrimaryHolderNumber = B.SecondaryHolderNumber
I think you want a CASE expression:
SELECT c.CustomerNumber,
(CASE WHEN EXISTS (SELECT 1
FROM ods.holderDim hd
WHERE c.PrimaryHolderNumber = hd.SecondaryHolderNumber
) AND
EXISTS (SELECT 1
FROM ods.holderOwesDim hod
WHERE c.PrimaryHolderNumber = hod.SecondaryHolderNumber
THEN 'Primary' ELSE 'Secondary'
)
END) as role
FROM ods.CustomerFact c;

How to exclude a row based on a match between two columns where one column has multiple values

I need to exclude records based on a match between two column values. One column value is the same for each row (Referring Associate), but the other (Sales Team) can contain multiple values.
In the example below, I do not want to return any Transaction IDs where the Referring ID exists in the Sales Team column. In other words, if the Referring ID matches any of the Sales Team values, then nothing should be returned.
I've tried the obvious
where Sales Team <> Referring Associate
but I end up returning the other 3 records where this condition is false.
EDIT:
Sample Data:
Expected Output:
Explanation:
All of the rows with a red Transaction ID should not be returned in the query results based on a match between Sales Team and Referring Associate.
Is this what you want?
select t.*
from t
where not exists (select 1
from t t2
where t2.transactionid = t.transactionid and
t2.salesteam = t.referringassociate
);
This query:
select referring_associate from tablename
where referring_associate = sales_team
returns all values of referring_associate that should be excluded.
So use it in this:
select * from tablename
where
referring_associate not in (
select referring_associate from tablename
where referring_associate = sales_team
)
to return all the other rows.
SELECT SalesTeams.*
FROM dbo.MyTest AS SalesTeams
LEFT JOIN dbo.MyTest ReferringAssociates ON SalesTeams.associateCode = ReferringAssociates.salesTeamCode
WHERE ReferringAssociates.salesTeamCode IS NULL

Oracle SQL Developer - Count function

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;

how to compare SQL dates with null

I want to count the number of rows having date is null.i tried following
SELECT R.COUNTRY_CD,COUNT(R.EFFECTIVE_END_DT) AS d_null
FROM REIMBURSEMENT R
GROUP BY R.COUNTRY_CD,R.EFFECTIVE_END_DT
HAVING R.COUNTRY_CD = #COUNTRY_CD AND R.EFFECTIVE_END_DT IS NULL
but it's giving d_null as 0...
how can i compare a date for NULL
COUNT only counts non-NULL entries.
Try COUNT(*) or COUNT(1) instead of COUNT(R.EFFECTIVE_END_DT).
Since you provide a Country_CD as parameter, and you only want NULL dates, you can probably simplify your query to:
SELECT R.Country_CD, COUNT(*) AS d_null
FROM Reimbursement R
WHERE R.Country_CD = #Country_CD AND R.Effective_End_DT IS NULL
Try this
SELECT R.COUNTRY_CD,COUNT(R.EFFECTIVE_END_DT) AS d_null
FROM REIMBURSEMENT R
GROUP BY R.COUNTRY_CD,R.EFFECTIVE_END_DT
HAVING R.COUNTRY_CD = #COUNTRY_CD AND DATE_FORMAT(R.EFFECTIVE_END_DT,"%y") IS NULL

SQL get rows matching ALL conditions

I would like to retrieve all rows matching a set of conditions on the same column. But I would like the rows only if ALL the conditions are good, and no row if only one condition fails.
For example, taking this table:
|id|name|
---------
|1 |toto|
|2 |tata|
I would like to be able to request if "tata" && "toto" are in this table. But when asking if "tata" and "tuto" are in, I would like an empty response if one of argument is in not in the table, for example asking if "toto" && "tutu" are included in the table.
How can I do that ?
Currently, I'am doing one query per argument, which is not very efficient. I tried several solutions including a subselect or a group+having, but no one is working like I want.
thanks for your support !
cheers
This isn't the most efficient way, but this query would work.
SELECT * FROM table_name
WHERE (name = 'toto' OR name = 'tata')
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'toto') > 0
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'tata') > 0
This is a little vague. If the names are unique, you could count the matching rows that match a where clause:
where name='toto' or name='tata'
If the count is 2, then you know both matched. If name is not unique you could potentially select the first ID (select top 1 id ...) that matches each in a union and count those with an outer select.
Even if you had an arbitrary number of names to match, you could create a stored procedure or code in whatever top-level language you are using to build the select statement.
SELECT 1 AS found FROM hehe
WHERE 1 IN (SELECT 1 FROM hehe WHERE name='tata')
AND 1 IN (SELECT 1 FROM hehe WHERE name='toto')
If name is unique you can simplify to:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(*) FROM tbl WHERE name IN ('toto', 'tata')) > 1;
If it isn't:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND EXISTS (SELECT * FROM tbl WHERE name = 'toto')
AND EXISTS (SELECT * FROM tbl WHERE name = 'tata');
Or, in PostgreSQL, MySQL and possibly others:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(DISTINCT name) FROM tbl WHERE name IN ('toto', 'tata')) > 1;