Different WHERE clause depending on subquery result - sql

I would like to SELECT WHERE column IS NULL or =value depending on result of subquery.
Here is an example incorrect solution that demonstrates the problem:
SELECT *
FROM table
WHERE column=(
SELECT (CASE WHEN COUNT(*) = COUNT(COLUMN) THEN MIN(column) END)
FROM table
)
When the subquery returns NULL the other query will return nothing because column=NULL is never true. How do I fix this?
(Subquery source: https://stackoverflow.com/a/51341498/7810882)

From your question. just add OR column IS NULL in where clause.
You will get the subquery condition or column IS NULL data.
SELECT *
FROM table
WHERE column= (
SELECT (CASE WHEN COUNT(*) = COUNT(COLUMN) THEN MIN(column) END)
FROM table
) OR column IS NULL

If you are only looking for one row, I would suggest:
select t.*
from table t
order by column nulls first
fetch first 1 row only;

Related

Compare the data of three column and set the flag in fourth column

I have above table structure, where 1st, 3rd and 5th row are same. There might be many records in the table, but I have used it just as a example. So if the data of Column A, Column B and Column C are same then I have to update Flag column as Yes otherwise No. I'm using SQL Server 2019.
I tried to update the only 'Yes' in the flag column with the following Query:
update table set Flag='Yes' where (SELECT Column A, Column B, Column C, COUNT(*) FROM Table GROUP BY Column A, Column B, Column C HAVING COUNT(*)>1 )
But getting following error:
An expression of non-boolean type specified in a context where a condition is expected, near ')'.
Any help would be appreciated.
An updatable CTE seems to be what you are after:
WITH CTE AS(
SELECT Flag,
COUNT(*) OVER (PARTITION BY ColumnA, ColumnB, ColumnC) AS DupeCount
FROM dbo.YourTable)
UPDATE CTE
SET Flag = CASE DupeCount WHEN 1 THEN 'No' ELSE 'Yes' END;
If you want to update, you can use an updatable CTE:
with toupdate as (
select t.*, count(*) over (partition by a, b, c) as cnt
from t
)
update toupdate
set flag = 'yes'
where cnt > 1;
I would suggest fixing the table so rows are not 100% duplicated -- but perhaps you have other columns that are not mentioned in the question.

SELECT specific ONLY if exists, otherwise return ALL

How can I write WHERE cluase so it returns rows that meet the criteria, if there are no such records it should return all records from a table?
Using UNION ALL:
select t.* from table t where condition
union all
select t.* from table t cross join (select count(*) cnt from table where condition) c
where c.cnt=0
Or (much more efficiently):
select col1, col2, ... colN
from
(
select t.*, sum(case when condition then 1 else 0 end) over() cnt from table
) s
where condition or s.cnt=0
Replace condition with your WHERE condition
One method you could consider in t-sql is to use ##rowcount to determine if you need to return all rows.
The benefit of doing so is you get two separate execution plans, one only optimised for your first exists criteria and would be beneficial if the majority of results are where the exists condition is met.
select <columns>
from <table>
where <condition>
if ##rowcount=0
begin
select <columns>
from <table>
end
One way would be:
SELECT *
FROM Person
WHERE
Name = 'John'
OR NOT EXISTS(SELECT null FROM Person WHERE Name = 'John')
I don't like it, for all those good reasons mentioned in the comments. If I was handed this requirement as part of a system I was creating I'd probably examine the need for the requirement; selecting all rows from a table is seldom useful if it's the sort of table that you query with a criteria: "Dear user, we couldn't find your person named John so here are the other 4.27 billion users in the system, pagination size 100"
that satisfies me enough:
WHERE (
ISNULL(#variable, '') = ''
OR #variable = [Column]
)
Not exactly what I described above but it returns all the records if condition is not met. However in that case condition would be assigning a value to variable.
1st method
Where ( ISNULL(#Param,'')='' OR ColumnName = #Param)
2nd way
WHERE ( ColumnName =CASE WHEN #Param IS NULL THEN ColumnName
ELSE #Param
END)
3rd way
WHERE (#Param ='' OR #Param =ColumnName)
I would recommend a CTE with not exists:
with cte as (
select t.*
from t
where . . .
)
select *
from cte
union all
select *
from t
where not exists (select 1 from cte);

Why does count( distinct ) with NULL columns return 0 in Hive SQL?

I have struggled with an issue in Hive SQL and just found out what the issue was:
select distinct 'A', NULL;
returns 'A', NULL
select count(distinct 'A', NULL);
returns 0
select count(distinct 'A', coalesce(NULL,''));
returns 1.
I was using the select line inside of a larger query and filtered on the result (=1). With the outcome being 0, I lost a lot of rows.
How come that a row with NULL column does not contribute to the result of a count(distinct) query?
It's the interface of count in hive:
count(*) counts all rows
count(col1) counts all rows where col1 is not null
count(distinct col1,col2...) counts all distinct rows where the specified columns are not null
As a solution to your specific problem, you can try to have a nested query with the logic and use count(*) in the outer query:
select count(*) from (select distinct 'A', NULL) a;
returns 1

Using a value from one query in second query sql

SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
This produces the result
AS COUNT
5 2
I then want to use the AS value in another query and only output the end result. Is this possible.i was thinking something like.
SELECT *
FROM
TABLE 2
Where AS =(
SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
);
This is called a subquery. To be safe, you would use in instead of = (and as is a bad name for a column, because it is a SQL key word):
SELECT *
FROM TABLE2
WHERE col IN (SELECT col
FROM Table1
GROUP BY col
HAVING COUNT(col) > 1
);
Your first query is also incorrect, because the having clause goes after the group by.
You could use a subquery with the in operator:
SELECT *
FROM table2
WHERE AS IN (SELECT AS
FROM table1
GROUP BY AS
HAVING COUNT(*) > 1)

Get frequency of a column in SQL Server

I have a column with values like 1,1,2,1,... and I would want to get the frequency of 1 and 2, I did
SELECT count(column)
FROM table
WHERE column = 1;
SELECT count(column)
FROM table
WHERE column = 2;
But, could I take the frequency with a more direct way?
Use aggregate functions
Select column, count(*)
From table
Group By column
This will return one row that contains the count, for each distinct value in column
One row each value:
select column 'value', count (column) 'Frequency'
from table
group by column
if only 2 values this give you both results in one row
select sum(case when column=1 then 1 else 0 end) as '1 Frequency',
sum(case when column=2 then 1 else 0 end) as '2 Frequency'
from table
You can try distinct function, like this
SELECT count( distinct column) FROM table;