Oracle select query conditions - sql

I have a search jsp, which has more than one criteria( ID OR NAME OR DATE OR ...) for searching the database. I need a single select query to satisfy all the condition. I have written the select query partially, but it is not working well. Please help me in finishing the query
select * from table 1
where Id in ( select id from table 1 where ( those three conditions here)
i have (1=? or id=?)
and (1=? or name=?)
and (1=? or date =?)
but it returns the full table. I know those three condition returns true. How to modify that in order to obtain the result. I don't want any stored procedure, as i am a newbie

If your conditions are true for every row, you'll get the full table.
For example, if your variable is 1, 1 = 1 will be true, and every row will be returned.
p,s, I don't understand why you've nested the select.

You've got a redundant subquery.
I assume the first parameter will be 1 if the second parameter is null, and 0 if the second parameter is not null; likewise the 3rd parameter will 1 if the 4th parameter is null, and 0 if the 4th parameter is not null, etc.?
Try this:
select * from table
where (1=? or id=?)
and (1=? or name=?)
and (1=? or date =?)
For example, if the user was searching by name I'd expect the parameters to be something like (1,NULL,0,'SMITH',1,NULL).
(Also, you can't use 1 for the table alias.)

select * from table 1
where Id in ( select
(case
when (1=? or id=?) and (1=? or name=? ) and (1=? or date =?) then id
end) as id from table 1 )
I hope this is what you are looking for

Related

SQL WHERE Clausule to get rows depending on the database content

Use case:
I have the customer_id and the task_id.
The database will always contain registers with a filled customer_id and empty task_id.
Sometimes will have the task_id filled. (as the example below)
Example 1
SELECT *
FROM table
WHERE customer_id = 11422412
AND task_id = 28870055
Here I expect to return the last two rows.
Example 2
SELECT *
FROM table
WHERE customer_id = 11432515
AND task_id = 22256884
Here I expect to return the only empty row.
Question:
How do I create a SQL Query to make sure that, in case the task_id exists in the database, I only return the records with task_id?
You could do something like the following with LIMIT. This will match the empty task_id and the set task_id (if it exists), order them so that the row with non-empty task_id comes first (if it exists), then return only the first one. (NULLS LAST is default sorting behavior in Postgre)
SELECT *
FROM table
WHERE customer_id = 11432515
AND (task_id = 22256884 OR task_id IS NULL)
ORDER BY task_id
LIMIT 1
I am assuming that you always want exactly one row like in your examples.
But there are other ways of doing it depending on your specific scenario (if your final query is more complicated than your examples).
Edited to add another way to handle case where more than one row matches customer_id and task_id:
SELECT *
FROM table t1
WHERE customer_id = 11432515
AND (task_id = 22256884
OR (
task_id is null
AND NOT EXISTS (SELECT * FROM table t2 WHERE t2.customer_id = 11432515 AND t2.task_id = 22256884)
)
)
This doesn't look super elegant, but it should work and you could use it as a starting point at least.

Select / Merge user specific rows with additional fallback rows in PostgreSQL

Setup: Postgresql table with a customer_id and a request_id column (+ additional not relevant data).
The rows with customer_id set to NULL work as a fallback/default.
Example what the table looks like:
Goal: I want to select all rows from the table for a given customer (e.g. where customer_id = 2).
For any existent request_id: If there are no entries for the given customer, return the fallback rows (where customer is null).
So the result should look like this:
Any idea how to write the select statement for postgresql? I'm kind of stuck and couldn't really find anything helpful so far. Thanks!
This is a strange requirement.
select t.*
from t
where t.customer_id = 2 or
(t.customer_id is null and
not exists (select 1 from t t2 where t2.request_id = t.request_id and t2.customer_id = 2)
);
For performance, I would recommend an index on (request_id, customer_id).

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'

How do I check if all posts from a joined table has the same value in a column?

I'm building a BI report for a client where there is a 1-n related join involved.
The joined table has a field for employee ID (EmplId).
The query that I've built for this report is supposed to give a 1 in its field "OneEmployee" if all the related posts have the same employee in the EmplId field, null if it's different employees, i.e:
TaskTrans
TaskTransHours > EmplId: 'John'
TaskTransHours > EmplId: 'John'
This should give a 1 in the said field in the query
TaskTrans
TaskTransHours > EmplId: 'John'
TaskTransHours > EmplId: 'George'
This should leave the said field blank
The idea is to create a field where a case function checks this and returns the correct value. But my problem is whereas there is a way to check for this through SQL.
select not count(*) from your_table
where employee_id = GIVEN_ID
and your_field not in ( select min(your_field)
from your_table
where employee_id = GIVEN_ID);
Note: my first idea was to use LIMIT 1 in the inner query, but MYSQL didn't like it, so min it was - the points to use any, but only one. Min should work, but the field should be indexed, then this query will actually execute rather fast, as only indexes would be used (obviously employee_id should also be indexed).
Note2: Do not get too confused with not in front of count(*), you want 1 when there is none that is different, I count different ones, and then give you the not count(*), which will be one if count is 0, otherwise 0.
Seems a job for a window COUNT():
SELECT
…,
CASE COUNT(DISTINCT TaskTransHours.EmplId) OVER () WHEN 1 THEN 1 END
AS OneEmployee
FROM …

How to get one common value from Database using UNION

2 records in above image are from Db, in above table Constraint are (SID and LINE_ITEM_ID),
SID and LINE_ITEM_ID both column are used to find a unique record.
My issues :
I am looking for a query it should fetch the recored from DB depending on conditions
if i search for PART_NUMBER = 'PAU43-IMB-P6'
1. it should fetch one record from DB if search for PART_NUMBER = 'PAU43-IMB-P6', no mater to which SID that item belong to if there is only one recored either under SID =1 or SID = 2.
2. it should fetch one record which is under SID = 2 only, from DB on search for PART_NUMBER = 'PAU43-IMB-P6', if there are 2 items one in SID=1 and other in SID=2.
i am looking for a query which will search for a given part_number depending on Both SID 1 and 2, and it should return value under SID =2 and it can return value under SID=1 only if the there are no records under SID=2 (query has to withstand a load of Million record search).
Thank you
Select *
from Table
where SID||LINE_ITEM_ID = (
select Max(SID)||Max(LINE_ITEM_ID)
from table
where PART_NUMBER = 'PAU43-IMB-P6'
);
If I understand correctly, for each considered LINE_ITEM_ID you want to return only the one with the largest value for SID. This is a common requirement and, as with most things in SQL, can be written in many different ways; the best performing will depend on many factors, not least of which is the SQL product you are using.
Here's one possible approach:
SELECT DISTINCT * -- use a column list
FROM YourTable AS T1
INNER JOIN (
SELECT T2.LINE_ITEM_ID,
MAX(T2.SID) AS max_SID
FROM YourTable AS T2
GROUP
BY T2.LINE_ITEM_ID
) AS DT1 (LINE_ITEM_ID, max_SID)
ON T1.LINE_ITEM_ID = DT1.LINE_ITEM_ID
AND T1.SID = DT1.max_SID;
That said, I don't recall seeing one that relies on the UNION relational operator. You could easily rewrite the above using the INTERSECT relational operator but it would be more verbose.
Well in my case it worked something like this:
select LINE_ITEM_ID,SID,price_1,part_number from (
(select LINE_ITEM_ID,SID,price_1,part_number from Table where SID = 2)
UNION
(select LINE_ITEM_ID,SID,price_1,part_number from Table SID = 1 and line_item_id NOT IN (select LINE_ITEM_ID,SID,price_1,part_number from Table SID = 2)))
This query solved my issue..........