Use WHERE clause only if item is set, otherwise select all rows - sql

In my Apex Oracle application I have a report using this sql query:
select ID,
NAME,
ADDRESS,
TYPE,
COMPANY_ID as "Company"
from WORKSTATIONS where COMPANY_ID = :P11_FILTER
which filters data by value of :P11_FILTER item. Now I need to select all rows if :P11_FILTER is not set or is NULL. How could I modify the where clause in order to achieve that?

You could use coalesce() or nvl():
where COMPANY_ID = coalesce(:P11_FILTER, COMPANY_ID)
coalesce(:P11_FILTER, COMPANY_ID) returns COMPANY_ID when :P11_FILTER is null.
Note that this where clause does not match in the situation where both COMPANY_ID and the parameter are NULL. This is different from the OR solution, that would returns the NULL row here.

One method uses or:
where COMPANY_ID = :P11_FILTER or :P11_FILTER is null

Related

Determine the number of times a null value occurs in column B for a distinct value in column A, SQL table

I have a SQL table with "name" as one column, date as another, and location as a third. The location column supports null values.
I am trying to write a query to determine the number of times a null value occurs in the location column for each distinct value in the name column.
Can someone please assist?
One method uses conditional aggregation:
select name, sum(case when location is null then 1 else 0 end)
from t
group by name;
Another method that involves slightly less typing is:
select name, count(*) - count(location)
from t
group by name;
use count along with filters, as you only requires Null occurrence
select name, count(*) occurances
from mytable
where location is null
group by name
From your question, you'll want to get a distinct list of all different 'name' rows, and then you would like a count of how many NULLs there are per each name.
The following will achieve this:
SELECT name, count(*) as null_counts
FROM table
WHERE location IS NULL
GROUP BY name
The WHERE clause will only retrieve records where the records have NULL as their location.
The GROUP BY will pivot the data based on NAME.
The SELECT will give you the name, and the COUNT(*) of the number of records, per name.

Select another column value from the same table if another column value is NULL

I have a table with four columns: NAME, AGE, PRIMARYWEIGHT and SECONDARYWEIGHT
Where NAME = 'Damian', I wish to select AGE and PRIMARYWEIGHT only if SECONDARYWEIGHT is NULL otherwise I'll take PRIMARYWEIGHT.
Ideally I'd like to give its an alias 'WEIGHT' regardless of whether it was PRIMARYWEIGHT or SECONDARYWEIGHT.
SELECT NAME, AGE, ISNULL(PRIMARYWEIGHT, SECONDARYWEIGH) As WEIGHT
msdn reference
SELECT AGE, COALESCE(SECONDARYWEIGH, PRIMARYWEIGHT) As WEIGHT
You can use COALESCE (as indicated in your tag)
Evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL.

Unable to retrieve NULL data

I have three fields Category, Date, and ID. I need to retrieve data that does not belong under certain ID. Here is an example of my query:
SELECT Category, Date, ID
FROM table
WHERE ID NOT IN('1','2','3')
AND Date = '01/06/2015'
After running this query I should only get records that do not have any ID meaning NULL values because for yesterday's record only ID 1,2,3 exist and rest do not have any value (NULL). For some reason when I run the query it takes away the NULL values as well so I end up with 0 rows. This is very stranger to me and I do not understand what is the cause. All I know that the ID numbers are string values. Any suggestions?
Try this. NULL values cannot not be equated to anything else.
SELECT Category, Date, ID
FROM table
WHERE (ID NOT IN('1','2','3') OR ID IS NULL)
AND Date = '01/06/2015'
Others have already shown how to fix this, so let me try to explain why this happens.
WHERE ID NOT IN('1','2','3')
is equivalent to
WHERE ID <> '1' AND ID <> '2' AND ID <> '3'
Since NULL <> anything yields UNKNOWN, your expression yields UNKNOWN and the record in question is not returned.
See the following Wikipedia article for details on this ternary logic:
Null (SQL): Comparisons with NULL and the three-valued logic (3VL)
Take a look at NULL comparison search conditions.
Use the IS NULL or IS NOT NULL clauses to test for a NULL value. This
can add complexity to the WHERE clause. For example, the TerritoryID
column in the AdventureWorks2008R2 Customer table allows null values.
If a SELECT statement is to test for null values in addition to
others, it must include an IS NULL clause:
SELECT CustomerID, AccountNumber, TerritoryID
FROM AdventureWorks2008R2.Sales.Customer
WHERE TerritoryID IN (1, 2, 3)
OR TerritoryID IS NULL
If you really want to be able to compare values to NULL's directly, you can do that as well. This is also described in the above article:
Transact-SQL supports an extension that allows for the comparison
operators to return TRUE or FALSE when comparing against null values.
This option is activated by setting ANSI_NULLS OFF.
Are you sure about you want ID fields as null?
Here is how you do it: (Assumins rest of your query is ok)
SELECT Category, Date, ID
FROM table
WHERE ID IS NULL
AND Date = '01/06/2015'
If you want records that does not have a category than you need to change your query as
SELECT Category, Date, ID
FROM table
WHERE Category IS NULL
AND Date = '01/06/2015'
You got a couple of options:
SELECT Category, Date, ID
FROM table
WHERE ISNULL(ID, '4') NOT IN('1','2','3')
AND Date = '01/06/2015'
Or what su8898 said
Please note that when you use "IN" or "NOT IN" which will not fetch any values if the column has got NULL values..
In your case, if you want to fetch only records with ID=NULL, then you can try the solution vgSefa suggested above..
If you want to pull all records with NULL as well as ID NOT IN('1','2','3'), then you could try something like this..
SELECT Category, Date, ID
FROM table
WHERE ID IS NULL
AND Date = '01/06/2015'
UNION ALL
SELECT Category, Date, ID
FROM table
WHERE ID NOT IN('1','2','3')
AND ID IS NOT NULL
AND Date = '01/06/2015'
Try this:
SELECT Category, Date, ID
FROM table
WHERE ID N
AND Date = '01/06/2015'

find unique rows using SQL?

I want to return all the rows from a table which are unique. I.e. if a certain field in two rows contain the same name, that name shouldn't be shown.
Since you want only the uniques names (and not an unique row for every names like you could have with DISTINCT), you have to use a GROUP BY and a HAVING (instead of a WHERE, because your parameter is the result of a function, not a variable) :
SELECT name FROM myTable GROUP BY name HAVING COUNT(name) = 1
SELECT DISTINCT column_name FROM table
If you want the complete rows, then use row_number() or distinct on:
select distinct on (name) t.*
from table t
order by name;

get values from sql rows with same name but different values

i need help concerning a sql query. first of all, i have a database with the following structure (example):
ID NAME VALUE
123 ABC_A Text Text Text
123 ABC_A Some more Text
123 ABC_A Even more Text
123 ABC_B some other text
now, i want to get all the different values of rows with the name "ABC_A". i tried to get those via group by and having, without success.
IS this what you want?
SELECT DISTINCT Value
FROM tableName
WHERE ID = 123 AND Name = 'ABC_A'
but if the value of the ID and Name are unique then you can omit distinct (to avoid overkilling the server)
SELECT Value
FROM tableName
WHERE ID = 123 AND Name = 'ABC_A'
Additional to John, if you use the keyword Distinct you onle get DIFFERENT Values, therefore
SELECT DISTINCT Value
FROM tableName
WHERE ID = 123 AND
Name = 'ABC_A'
i want to get all the different values of rows with the name "ABC_A"
This would be for example:
SELECT value, count(value) FROM tbl WHERE name = 'ABC_A' GROUP BY value;
If you do not need the count of times one value appears, remove it, or use DISTINCT:
SELECT DISTINCT value FROM tbl WHERE name = 'ABC_A';
If you want the different values of rows by ID also,
SELECT value, count(value)
FROM tbl
WHERE id = 123 AND name = 'ABC_A'
GROUP BY value;
Or if you want "ALL" the different values (with duplicates too) remove the GROUP BY (and you no longer can use the count(), which would be always 1):
SELECT value FROM tbl WHERE id = 123 AND name = 'ABC_A';
The GROUP BY statement is used in conjunction with the aggregate functions to group the result-set by one or more columns.
In above case why dont you use simple where clause
select * from <tableName> where name ='ABC_A'