Find values which are present in all columns in a Cable - sql

I would like a SQL Server query which finds the Values in a cell which fills multiple columns. For example, if I have table
ID Value1 Value2 Value3
1 2 NULL NULL
1 NULL 3 NULL
1 NULL NULL 4
1 3.4 NULL NULL
2 NULL 3 NULL
2 NULL NULL NULL
3 NULL NULL 91
As in the table above, only 2 of the columns can be filled at a time(First is ID and 2nd is either of Value1, 2 or 3) and ID can be repeated multiple times.
I want to return the ID as only 1 because 1 is the only ID that populates all the three other columns. 2 fills only Value2 and all the other values of 2nd iteration of 2 are NULL where as 3 is present only in Column Value3. Is there someway that I can find the Id's which fill all the other columns.
I would love to do this preferably without a cursor but I can go for cursor if it's compulsory. Thanks
EDIT
Desired Table:
ID
1
The Statement should return only the filtered IDs which populate all the other columns.

Try this
SELECT id,
FROM TableName
GROUP BY id
HAVING MAX(value1) IS NOT NULL AND
MAX(value2) IS NOT NULL AND
MAX(value3) IS NOT NULL

Something for you try if you want some less lines of code:
select ID from dbo.Table_1 group by ID having count(Value1) > 0 AND count(Value2) > 0 AND count(Value3) > 0

Related

DB2-Find the count of number of occurrences of different values for each primary key in a table

I have a table like
ID
value
1
ABC
1
ABC
1
ABCD
2
ABC
Column 2 can either have ABC or ABCD
Now I want to find the count for values in column 2 for each ID
ID
count (ABC)
count (ABCD)
1
2
1
2
1
0
How to write DB2 query to get the output in the above format for count?
Found a solution
Select ID, sum(decode(value, 'ABC',1,0)) as count_abc
, sum(decode(value, 'ABCD',1,0)) as count_abcd
from table
group by ID

Get the last non null value of a table column

Below is my table and from column B I want to get the value 3 in results.
A
B
1
1
2
Null
3
2
4
Null
5
3
6
Null
7
Null
8
Null
Case not working: it should return 10
A
B
1
1
2
Null
3
2
4
Null
5
3
6
Null
7
Null
8
10
Use a LIMIT query:
SELECT *
FROM yourTable
WHERE B IS NOT NULL
ORDER BY A DESC
LIMIT 1;
Do you want to get the value '3' because it is the largest in 'B' column?
If so, you can run the following query:
SELECT *
FROM Table
WHERE B IS NOT NULL
ORDER BY B DESC
LIMIT 1;
There is not much to go on in the question. However, assuming that you can order by the col A, the answer would be
SELECT * from table
where B is not NULL
Order by A DESC
Limit 1
If A is numeric, then the order by works fine and you get all 3 non null values from column B. Then Order by descending + limit 1 will ensure you get last value of B
You already received really good answers that should help you. I just want to add a futher propose that works fine if both A and B are numeric and they are always sorted like in your example, meaning the highest b entry always has the highest a value.
SELECT MAX(b) FROM tableB
WHERE b IS NOT NULL
HAVING MAX(a);

Merging rows with the same id

I have many tables in my db which has: RowID, ProductID and Numeric Value (Numeric value can be NULL, what means infinity). In table can be many Rows with the same ProductId. Is this possible to make function that take some of this tables (not all, only chosen by me) and return new table which contains all ProductId from each table but there is only one ProductId in table and Numeric Value is sum of all rows from each table. E.g
Table1:
RowID ProductID Numeric Value
0 1 1.5
1 1 3.5
2 2 4
Table2:
RowID ProductID Numeric Value
0 1 6
1 3 1.25
2 3 NULL
Return Table:
ProductID Numeric Value
1 11 (1.5+3.5+6)
2 4
3 NULL (1.25 + NULL)
*it also can return 0 instead of NULL, all Numeric Values are positive so 0 can represent infinity
I think you can first combine 2 columns and then group them -
SELECT PID, CASE WHEN COUNT(*) = COUNT(NV) THEN SUM(NV) ELSE NULL END
FROM (SELECT ProductID PID, Numeric Value NV
FROM TABLE_1
UNION ALL
SELECT ProductID, Numeric Value
FROM TABLE_2) T
GROUP BY PID

Group multiple rows together

I have a table which contains the following and I am looking to group them to get the below output. Is it possible?
Input
ID Value1 Value2 Value3
5 Y NULL NULL
5 NULL 1 NULL
5 NULL NULL USA
5 NULL NULL NULL
6 N NULL NULL
6 NULL 2 NULL
6 NULL NULL GBP
6 NULL NULL NULL
Output
ID Value1 Value2 Value3
5 Y 1 USA
6 N 2 GBP
Group by the id and use max() to get the non-null value per each group
select id,
max(value1) as value1,
max(value2) as value2,
max(value3) as value3
from your_table
group by id
BTW you should think about changing you table design. It is not normalized.

Select distinct not-null rows SQL server 2005

I ran into the following problem.
I have a table like this:
ID ID1 ID2 ID3 ID4 ID5
1 NULL NULL NULL NULL 1
2 NULL NULL NULL 2 NULL
3 NULL NULL NULL 2 1
4 3 NULL NULL 2 NULL
5 3 NULL NULL 2 1
6 NULL 5 NULL 2 NULL
And I need to get distinct rows it terms that NULL equals any value. For this example the answer is:
ID ID1 ID2 ID3 ID4 ID5
5 3 NULL NULL 2 1
6 NULL 5 NULL 2 NULL
P.S. Here ID is primary key hence unique. ID1-ID5 - any integers.
Thanks in advance!
UPDATED
Saying that null equals any number I mean that it's absorbed by any number.
This works, don't know if it can be made any simpler
SELECT ID1, ID2, ID3, ID4, ID5
FROM IDS OUTT
WHERE NOT EXISTS (SELECT 1
FROM IDS INN
WHERE OUTT.ID != INN.ID AND
(ISNULL(OUTT.ID1, INN.ID1) = INN.ID1 OR (INN.ID1 IS NULL AND OUTT.ID1 IS NULL)) AND
(ISNULL(OUTT.ID2, INN.ID2) = INN.ID2 OR (INN.ID2 IS NULL AND OUTT.ID2 IS NULL)) AND
(ISNULL(OUTT.ID3, INN.ID3) = INN.ID3 OR (INN.ID3 IS NULL AND OUTT.ID3 IS NULL)) AND
(ISNULL(OUTT.ID4, INN.ID4) = INN.ID4 OR (INN.ID4 IS NULL AND OUTT.ID4 IS NULL)) AND
(ISNULL(OUTT.ID5, INN.ID5) = INN.ID5 OR (INN.ID5 IS NULL AND OUTT.ID5 IS NULL)))
EDIT: Found a sweeter alternative, if your ids never have negative numbers
SELECT ID1, ID2, ID3, ID4, ID5
FROM IDS OUTT
WHERE NOT EXISTS (SELECT 1
FROM IDS INN
WHERE OUTT.ID != INN.ID AND
coalesce(OUTT.ID1, INN.ID1,-1) = isnull(INN.ID1,-1) AND
coalesce(OUTT.ID2, INN.ID2,-1) = isnull(INN.ID2,-1) AND
coalesce(OUTT.ID3, INN.ID3,-1) = isnull(INN.ID3,-1) AND
coalesce(OUTT.ID4, INN.ID4,-1) = isnull(INN.ID4,-1) AND
coalesce(OUTT.ID5, INN.ID5,-1) = isnull(INN.ID5,-1))
EDIT2: There is one case where it won't work - in case two rows (with different ids) have exact same form. I am assuming that it is not there. If such a thing is present, then first create a view with a select distinct on the base table first, and then apply this query.
Statement of your problem as I understand it:
You start with the full table:
ID ID1 ID2 ID3 ID4 ID5
1 NULL NULL NULL NULL 1
2 NULL NULL NULL 2 NULL
3 NULL NULL NULL 2 1
4 3 NULL NULL 2 NULL
5 3 NULL NULL 2 1
6 NULL 5 NULL 2 NULL
Then you eliminate "duplicate" rows, ie. rows that have less, but the same values as other rows (except NULL — and the ID column is not included):
Row 1 is eliminated because row 3 is identical, but has more values in the places where row 1 has NULL.
Row 2 likewise gets eliminated by (either of) row 2 or 4.
Row 3 and 4 are eliminated by row 5.
You're then left with rows 5 and 6:
ID ID1 ID2 ID3 ID4 ID5
5 3 NULL NULL 2 1
6 NULL 5 NULL 2 NULL
My answer:
Frankly, I don't see how this could be done with SQL's SELECT DISTINCT, or more generally, with SQL's set-based logic. I could imagine that you might be able to do this kind of filtering with a more procedural approach (e.g. with cursors) — but I can't provide a solution for this.
A note about terminology:
NULL equals any value
NULL never equals any value, because NULL is itself not a value; it is the absence of a value. NULL essentially means "unknown". (The fact that NULL is not a value is the reason why you shouldn't write IDx = NULL, but IDx IS NULL instead.)
If ID1, ID2 (...) has always the same value, as in your example, you could do it
Select
SUM(id1)/COUNT(id1),
SUM(id2)/COUNT(id2),
SUM(id3)/COUNT(id3),
SUM(id4)/COUNT(id4),
SUM(id5)/COUNT(id5) From TABLE
The functions SUM and COUNT will ignore that null values.
But still little confused your question.. :)