How to set up independent queries within a single query - postgresql

I need to query a table for null values but on different fields. I have been setting up my queries independently and running them one at a time to view my results.
EX:
Query 1:
select * from TABLE1 where FIELD1 is null and FIELD2 is NOT null
Query 2:
Select * from TABLE1 where FIELD6 = 'YES' and FIELD2 is null
Query 3:
select * from TABLE1 where FIELD4 = 'OUTSIDE' and FIELD7 is not null
Is there a way to set up a single query which will allow me retrieve data from a single table but run queries where the conditions are different?

It looks like you could use the or operator:
select * from TABLE1
where (FIELD1 is null and FIELD2 is NOT null)
or (FIELD6 = 'YES' and FIELD2 is null)
or (FIELD4 = 'OUTSIDE' and FIELD7 is not null)

Related

How to change field value to null for certain conditions in a query?

I have a query where I select data from a table using TSQL. When one of the fields (field1) has a certain value, I want to change the value of two other fields (field2 and field3) to NULL depending on the value of field1. I've browsed stack overflow and see many answers saying to UPDATE the table like this:
UPDATE MyTable
SET MyField = NULL
WHERE MyField = ''
But Update changes a table, right? I don't want to change my table data. I want to change my query results. Is there a way to change results of a query like I want?
If you have table field1 | field2 | field3 and you want to query field2 and field3, but in the case of field1 is NULL, these two other field should be also NULL. So in your case:
SELECT field1
, CASE WHEN field1 IS NULL THEN NULL ELSE field2 END AS field2
, CASE WHEN field1 IS NULL THEN NULL ELSE field3 END AS field3
FROM dbo.MyTable
Update (1) after clarification in comment:
SELECT field1
, CASE WHEN field1 = 'IR' THEN NULL ELSE field2 END AS field2
, CASE WHEN field1 <> 'IR' THEN NULL ELSE field3 END AS field3
FROM dbo.MyTable
As described in CASE (Transact-SQL) documentation:
WITH Data (value) AS
(
SELECT 0
UNION ALL
SELECT 1
)
SELECT
CASE
WHEN MIN(value) <= 0 THEN 0
WHEN MAX(1/value) >= 100 THEN 1
END
FROM Data ;
Or in your case:
SELECT
MyField = CASE
WHEN MyField = '' THEN NULL
ELSE MyField
END
FROM MyTable
I did test runs just adding the two CASE statements to the Select part of my main query. Worked well. Thanks for the help!
Here are the exact statements I used. I named the resulting fields Case# and Payee instead of CaseNo and VendorName, because SQL was calling the results CaseNo1 and VendorName1:
CASE WHEN Accounting_Categories.Name LIKE 'I%' then NULL Else CaseNo END as Case#,
CASE WHEN Accounting_Categories.Name LIKE 'I%' then VendorName Else NULL END as Payee

How do I avoid listing all the table columns in a PostgreSQL returns statement?

I have a PostgreSQL function similar to this:
CREATE OR REPLACE FUNCTION dbo.MyTestFunction(
_ID INT
)
RETURNS dbo.MyTable AS
$$
SELECT *,
(SELECT Name FROM dbo.MySecondTable WHERE RecordID = PersonID)
FROM dbo.MyTable
WHERE PersonID = _ID
$$ LANGUAGE SQL STABLE;
I would really like to NOT have to replace the RETURNS dbo.MyTable AS with something like:
RETURNS TABLE(
col1 INT,
col2 TEXT,
col3 BOOLEAN,
col4 TEXT
) AS
and list out all the columns of MyTable and Name of MySecondTable. Is this something that can be done? Thanks.
--EDIT--
To clarify I have to return ALL columns in MyTable and 1 column from MySecondTable. If MyTable has >15 columns, I don't want to have to list out all the columns in a RETURNS TABLE (col1.. coln).
You just list the columns that you want returned in the SELECT portion of your SQL statement:
SELECT t1.column1, t1.column2,
(SELECT Name FROM dbo.MySecondTable WHERE RecordID = PersonID)
FROM dbo.MyTable t1
WHERE PersonID = _ID
Now you'll just get column1, column3, and name returned
Furthermore, you'll probably find better performance using a LEFT OUTER JOIN in your FROM portion of the SQL statement as opposed to the correlated subquery you have now:
SELECT t1.column1, t1.column2, t2.Name
FROM dbo.MyTable t1
LEFT OUTER JOIN dbo.MySecondTable t2 ON
t2.RecordID = t1.PersonID
WHERE PersonID = _ID
Took a bit of a guess on where RecordID and PersonID were coming from, but that's the general idea.

Most effective way to get value if select count(*) = 1 with grouping

Lets say I have table with ID int, VALUE string:
ID | VALUE
1 abc
2 abc
3 def
4 abc
5 abc
6 abc
If I do select value, count(*) group by value I should get
VALUE | COUNT
abc 5
def 1
Now the tricky part, if there is count == 1 I need to get that ID from first table. Should I be using CTE? creating resultset where I will add ID string == null and run update b.ID = a.ID where count == 1 ?
Or is there another easier way?
EDIT:
I want to have result table like this:
ID VALUE count
null abc 5
3 def 1
If your ID values are unique, you can simply check to see if the max(id) = min(id). If so, then use either one, otherwise you can return null. Like this:
Select Case When Min(id) = Max(id) Then Min(id) Else Null End As Id,
Value, Count(*) As [Count]
From YourTable
Group By Value
Since you are already performing an aggregate, including the MIN and Max function is not likely to take any extra (noticeable) time. I encourage you to give this a try.
The way I would do it would indeed be a CTE:
using #group AS (SELECT value, Count(*) as count from MyTable GROUP BY value HAVING count = 1)
SELECT MyTable.ID, #group.value, #group.count from MyTable
JOIN #group ON #group.value = MyTable.value
When using group by, after the group by statement you can use a having clause.
So
SELECT [ID]
FROM table
GROUP BY [VALUE]
HAVING COUNT(*) = 1
Edit: with regards to your edited question: this uses some fun joins and unions
CREATE TABLE #table
(ID int IDENTITY,
VALUE varchar(3))
INSERT INTO #table (VALUE)
VALUES('abc'),('abc'),('def'),('abc'),('abc'),('abc')
SELECT * FROM (
SELECT Null as ID,VALUE, COUNT(*) as [Count]
FROM #table
GROUP BY VALUE
HAVING COUNT(*) > 1
UNION ALL
SELECT t.ID,t.VALUE,p.Count FROM
#table t
JOIN
(SELECT VALUE, COUNT(*) as [Count]
FROM #table
GROUP BY VALUE
HAVING COUNT(*) = 1) p
ON t.VALUE=p.VALUE
) a
DROP TABLE #table
maybe not the most efficient but something like this works:
SELECT MAX(Id) as ID,Value FROM Table WHERE COUNT(*) = 1 GROUP BY Value

ISNULL usage with NULL database fields

I am trying to do something that should be fairly simple but ISNULL isn't doing what I thought it would.
Basically I have a stored procedure and I am expecting either PARAM1 OR PARAM2 to have a matching value in my table.
SELECT * FROM MyTable WITH (NOLOCK)
WHERE
field1 = ISNULL(#PARAM1 ,field1 )
AND
field2 = #PARAM2
This works fine until I have NULL fields in my row then it excludes those results. Is there a different method that can cater for this?
ISNULL replaces the first value with the second value, so only if your parameter #PARAM1 is NULL does it replace it with PARAM1. I assume you're not passing in NULL values, so that's probably not what you want. More likely you just want to say
WHERE
(Field1 = #PARAM1 OR Field1 IS NULL)
AND
Field2 = #Param2
I Suppose you could use ISNULL in this fashion too:
ISNULL(Field1, #PARAM1) = #PARAM1
null is special in sql. If you do any comparisons on a column any rows that have a null for that column will be excluded.
SELECT * FROM MyTable WITH (NOLOCK)
WHERE
(PARAM1 = #PARAM1 or PARAM1 is null)
AND
(PARAM2 = #PARAM2 or PARAM2 is null)
Use
field1 = ISNULL(#PARAM1, A_REPLACEMENT_VALUE_IF_PARAM1_IS_NULL)
This will evaluate to-
field1 = #PARAM1 if #PARAM1 IS NOT NULL.
field1 = A_REPLACEMENT_VALUE_IF_PARAM1_IS_NULL if #PARAM1 IS NULL
EDIT:
Try these:
--If you want to ignore the WHERE clause if PARAM1/2 is null
ISNULL(field1, DEFAULT_VALUE) = ISNULL(#PARAM1, ISNULL(field1, DEFAULT_VALUE))
OR
ISNULL(field2, DEFAULT_VALUE) = ISNULL(#PARAM2, ISNULL(field2, DEFAULT_VALUE))
OR
--To get all rows with field1/2 as PARAM1/2 and ignore everything else
field1 = #PARAM1 OR field2 = #PARAM2

How to check if a date is in a list of dates - TSQL

I am trying to create a SQL query that checks if a date is in a list of dates but my query doesn't work...
SELECT *
FROM TABLE1
WHERE field1 = value1
AND convert(nvarchar(15),date_start,101) IN
(SELECT convert(nvarchar(15),date_end,101)
FROM TABLE2
)
This query should return some values but it doesn't...
do not convert the data i think there is no need for this
Try this :
SELECT *
FROM TABLE1
WHERE field1 = value1
AND date_start IN
(SELECT date_end FROM TABLE2)