SQL select column with same key if all values are null - sql

I have two columns , ColumnA and ColumnB, occassionally columnB doesnt gets populated and it should e. I'm looking for a query that will only select if all ColumnA is unpopulated.
ColumnA|ColumnB
Apples|
Apples|
Apples|Orange
This is what i'm but this is incorrect because it says ColumnA is null with the same value and ColumnB is populated. I want the query only to return rows if all of columnB is unpopulated.
SELECT ColumnA
FROM tblMyTable
WHERE ColumnA IN
(SELECT ColumnA
FROM tblMyTableB
WHERE ColumnB IS NULL)

You current query gives you too many results. The ones you want to eliminate are those where there is a ColumnB value:
SELECT ColumnA
FROM tblMyTable
WHERE ColumnA IN
(SELECT ColumnA
FROM tblMyTableB
WHERE ColumnB IS NULL)
AND NOT ColumnA IN
(SELECT ColumnA
FROM tblMyTableB
WHERE ColumnB IS NOT NULL)
Or, smarter is:
select ColumnA,COUNT(ColumnB) from tblMyTable
group by ColumnA having COUNT(ColumnB) = 0
Because COUNT(Expression) only counts non-null expression values

It looks like your logic is backwards:
Your query finds values in column A where there is a NULL value in column B.
I think you want the values in column A where there isn't a non-NULL value in column B.
Try adding NOT in two places and add DISTINCT to avoid getting duplicate results:
SELECT DISTINCT ColumnA
FROM tblMyTable
WHERE ColumnA NOT IN
(SELECT ColumnA
FROM tblMyTableB
WHERE ColumnB IS NOT NULL)
In addition, if ColumnA can be NULL then you'll have to exclude those NULL values from your inner query otherwise the NOT IN expression will return NULL instead of True and so no results will be returned:
SELECT DISTINCT ColumnA
FROM tblMyTable
WHERE ColumnA NOT IN
(SELECT ColumnA
FROM tblMyTableB
WHERE ColumnA IS NOT NULL
AND ColumnB IS NOT NULL)

Using EXCEPT. This can be expressed as
Get Column A, EXCEPT where some non-null in Column B for that column A
DECLARE #MyTable TABLE (ColumnA varchar(20) NOT NULL, ColumnB varchar(20) NULL);
INSERT #MyTable VALUES
('Apple', NULL),('Apple', NULL),('Apple', 'Orange'),
('Banana', NULL),('Banana', NULL),
('Strawberry', 'Pie'), ('Strawberry', 'Pie')
SELECT ColumnA FROM #MyTable
EXCEPT
SELECT ColumnA FROM #MyTable WHERE ColumnB IS NOT NULL
More on EXCEPT: Why does EXCEPT exist in T-SQL?

Related

SELECT all distinct rows with two simple characteristic

I have this table in 18c Oracle Database:
CREATE TABLE TABLEA
(
COLUMNA NUMBER(5) NOT NULL,
COLUMNB NUMBER(5) NOT NULL
)
I've this rows:
Insert into TABLEA
(COLUMNA, COLUMNB)
Values
(96, 1011),
(96, 9130),
(848, 1011),
(848, 1172),
(1095, 1011),
(1095, 1172);
It should be very simple but I really stuck here.
I need to get all the different values of COLUMNA, when all COLUMNB from the same COLUMNA are in (1172, 1011, 1037).
Result expected:
COLUMNA
----------
848
1095
The value 96 shouldn't be returned, because there are a row with a value in COLUMNB that aren't in the condition.
Those values (1172, 1011, 1037) can be in a specific table with a single column if it helps.
I've tried this, but I just want the distinct values:
SELECT columnA, COUNT (*) OVER (PARTITION BY columnA)
FROM tableA
WHERE EXISTS
(SELECT 1
FROM tableB -- With (1172, 1011, 1037) in each row
WHERE COLUMNB = values)
GROUP BY COLUMNA
HAVING COUNT (*) > 1;
Is there any other solutions?
Maybe you should use DISTINCT to show non repeated values.
Have you tried something like this?
SELECT DISTINCT columnA FROM tableA WHERE columnB in (1172, 1011, 1037)
Maybe something like so, not 100% it's late here :)
select
columna
from
#tablea
group by columna
having count(*)=sum(case when columnb in (1172, 1011, 1037) then 1 else 0 end)

SQL: Add a SUM(ColumnA) AS ColumnB to a query returning ColumnA

I have a query that returns a number of columns, including ColumnA (which is numerical).
I want to add an additional column to the end of the query that returns the sum of ColumnA
ColumnA
ColumnB
10
37
20
37
5
37
2
37
SELECT
ColumnA,
SUM(ColumnA) AS ColumnB
FROM
Table
The code above doesn't work, but I'm not sure how to create something that will.
I think you need this query:
SELECT ColumnA, (SELECT SUM(ColumnA) FROM table) as ColumnB
FROM table
Something like
SELECT
ColumnA,
ColumnASum
FROM Table
LEFT JOIN (SELECT SUM(columnA) ColumnASum FROM Table)
ON TRUE;
Should work
You could create a variable of the SUM() first.
DECLARE #ColumnB int
SET #ColumnB = (SELECT SUM(ColumnA) FROM Table)
SELECT ColumnA, #ColumnB
FROM Table
This should give you what you need.
I would use CROSS APPLY.
SELECT Table.ColumnA
,CA.ColumnB
FROM Table
CROSS APPLY (SELECT SUM(ColumnA) ColumnB FROM Table) CA
You basically define a subquery that outputs an aggregate value that you can have as another column.

Column update and insert 2 rows within the same table

I have a table named table1 and the value in one columnA is X. So when this value is X we need to insert 2 new rows and update the columnA with values Z and Y.
Is it possible with an insert and Update statement?
I am thinking of below query to update the column but how to insert the two rows.
select * from table1 where columnA = 'x'
Update columnA ='Z'
You could use the following statements to insert in the table
INSERT INTO table1
SELECT 'y' columnA,
columnB,
columnC,
...
FROM table1
WHERE columnA = 'x';
INSERT INTO table1
SELECT 'z' columnA,
columnB,
columnC,
...
FROM table1
WHERE columnA = 'x';
But of course, you still need to provide criteria in WHERE clause to get the specific data you wanted replicated in the same table but with different columnA value. You really need to specify each column.

Group BY on Condition basis

I have data in following way....
ColumnA ColumnB
7675 22838
7675 24907
7675 NULL
I want the results in following way.....
ColumnA ColumnB
7675 2 (need total count for Not Null value)
7675 0 (need count 0 for NULL value)
SELECT ColumnA, COUNT(ColumnB) ColumnB
FROM YourTable
GROUP BY ColumnA
UNION ALL
SELECT ColumnA, 0
FROM YourTable
WHERE ColumnB IS NULL
GROUP BY ColumnA
You could introduce a calculated column indicating whether ColumnB is null or not and use it as a grouping criterion together with ColumnA:
SELECT
t.ColumnA,
ColumnB = COUNT(t.ColumnB)
FROM
dbo.YourTable AS t
CROSS APPLY
(SELECT CASE WHEN t.ColumnB IS NULL THEN 1 ELSE 0 END) AS x (SubGroup)
GROUP BY
t.ColumnA,
x.SubGroup
ORDER BY
t.ColumnA,
x.SubGroup
;
The COUNT(t.ColumnB) expression would always be NULL for a null subgroup, and for the corresponding non-null subgroup it would return the number of the non-null entries.
select columnA,
count(columnB) as non_null_count,
sum(columnB is null) as null_count
from your_table
group by ColumnA
you could easily do with a count and sum which may be faster if there are a lot of rows rather than selecting all of the rows twice with a UNION
SELECT columna, columnb, SUM(mycount)
FROM
( SELECT *, COUNT(columnb) as mycount
FROM test
GROUP BY columnb
)t
GROUP BY mycount
ORDER BY CASE WHEN mycount = 0 THEN 1 ELSE 2 END DESC;
Fiddle Demo

sql query where null results get placed first

select *
from tableA
order by cast(columnA as int), column B.
This is my current query script. There is a scenario where there column A is null. And result rows where column A is null are pushed to the end.
Is there a way such that if columnA is null, put the rows before other rows where columnA is not null?
thanks.
Something along these lines should work if your dbms supports standard SQL.
select (case when columnA is null then 0 else 1 end) as sort_order, *
from tableA
order by sort_order, columnA, columnB;
Try like below... it will help you....
SELECT * FROM tableA ORDER BY (CASE WHEN columnA IS NULL THEN 1 ELSE 0 END) DESC,
CAST(columnA as int), column B
It display the NULL results before NOT NULL Results
I case of Oracle you can use order by columnA NULLS FIRST, columnB