Comparing rows in MS access tables - sql

I have such values in these two table. I want to check duplicates in TableA and TableB
TABLEA
StaffName Shift Hrs
ABC 1 12
DEF 23
XYZ 2
TABLEB
StaffN Sft Hrs
ABC 1 12
DEF 23
XYZ 2
However when i do a
SELECT * FROM TABLEA
WHERE NOT EXISTS
(SELECT * FROM TABLEB.StaffN = TABLEA.StaffName AND
TABLEB.Sft = TABLEA.Shift AND
TABLEB.Hrs = TABLEA.Hrs);
Why would i be returned of DEF and XYZ? is it becuz of the empty value? And how can i change my select statment to check if both value empty, its the same.

Yes, you were right to suspect Nulls.
Consider the 3 values in the "DEF" rows: DEF; Null; and 23. A human might say those rows are duplicates because all 3 values are the same in both tables.
However, the subquery asks the db engine to consider whether TABLEB.Sft = TABLEA.Shift. And there is the problem ... a Null can never be equal to anything, not even another Null.
See whether this Immediate window session clarifies the situation.
? 1 = 1
True
? 1 = 2
False
? 1 = Null
Null
? Null = Null
Null
So when both fields are Null, the comparison TABLEB.Sft = TABLEA.Shift is evaluated as Null. The db engine will only include rows where the comparison is True, so those "DEF" rows are excluded. And the same logic explains why the "XYZ" rows are excluded.
You need a comparison which returns True when both TABLEB.Sft and TABLEA.Shift are Null, and also returns True when both contain the same non-Null values.
(TABLEB.Sft Is Null AND TABLEA.Shift Is Null)
OR
(TABLEB.Sft = TABLEA.Shift)
Try this query:
SELECT *
FROM
TABLEA AS a
INNER JOIN TABLEB AS b
ON a.StaffName = b.StaffN
WHERE
(
(a.Shift Is Null AND b.Sft Is Null)
OR
(a.Shift = b.Sft)
)
AND
(
(a.Hrs Is Null AND b.Hrs Is Null)
OR
(a.Hrs = b.Hrs)
);

You could wrap your where criteria around the NZ function to see if that helps, like:
NZ(TABLEB.Hrs,0) = NZ(TABLEA.Hrs,0)

Related

SQL QUERY regarding single row as output

I want a query in which it only returns only one output row based on the values in a column.
What I need is
Table A has values
A
----|----
1 |
2 |
3 |
required output
A
----
yes
so I need a query in which if table a has 3 in its column then the output I need to get is yes or else no.
my code:-
WITH
number_tb AS (select * from t1),
out_put as (select case when a = 3 then 'yes' else 'no' end a_case from number_tb)
select * from out_put
output:-
a_case
-----
no
no
yes
I only need single row output. if 3 is present then yes or no, I don't need it for each row.
Is it possible to do so??
If a proper boolean true/false value is also acceptable, you can use
select exists (select * from t1 where a = 3) as a;
If you want a string with yes/no instead you can use a CASE expression to turn the boolean value into a string.
select case
when exists (select * from t1 where a = 3) then 'Yes'
else 'No'
end as a;

How to update a value in column based on value from other table in SQL server?

I have two tables match_score and match_condition
I want to update table match_condition and set values of innings, first_4, etc.
Here's the example in which I am trying to update table match_condition with innings value from match_score whenever both of them is not matched
UPDATE a
SET a.innings = b.innings
FROM match_condition a
INNER JOIN (SELECT TOP 1 * FROM match_score order by time_stamp desc ) b
ON a.matchid = b.matchid
WHERE a.innings != b.innings
match_score table
matchid time_stamp overs ball run team_score wicket innings
50821 2021-04-22 10:52:58.640 20 6 1 137 0 1
50821 2021-04-22 10:52:58.637 20 5 1 136 0 1
50821 2021-04-22 10:52:58.633 20 4 0 135 1 1
match_condition table
matchid seriesid match_time innings powerplay_over first_50 first_100 first_150 first_200 first_4 first_6 first_wicket
50820 2780 2021-04-19 18:44:12.360 NULL NULL NULL NULL NULL NULL NULL NULL NULL
50821 2780 2021-04-20 10:00:06.827 NULL NULL NULL NULL NULL NULL NULL NULL NULL
I made changes according to answers here , but still its showing 0 row affected
If value innings in match_condition will never be -1 this query will finish your job:
UPDATE
match_condition
SET
match_condition.innings = a.innings
FROM (
SELECT TOP 1 innings, matchid FROM match_score ORDER BY time_stamp DESC) a
WHERE
match_condition.matchid = a.matchid
AND
ISNULL(match_condition.innings, -1) <> a.innings
If you think that value can be somehow -1, just change in ISNULL operator value to sam 'unreal' number.
Here is DB FIDDLE demo
You can do it by using a subquery
UPDATE match_condition
SET match_condition.innings =
(
SELECT
CASE
WHEN match_condition.innings != b.innings THEN match_condition.innings
ELSE b.innings
END
FROM match_score b
WHERE match_condition.matchid = b.matchid
)
The issue with your query would appear to be that != returns not-true if either value is NULL. It is not appropriate.
You could fix your query as written. However, that would only work for one match in the second table. I would instead suggest apply:
UPDATE mc
SET mc.innings = ms.innings
FROM match_condition mc CROSS APPLY
(SELECT TOP 1 ms.*
FROM match_score ms
WHERE ms.matchid = mc.matchid
ORDER BY time_stamp DESC
) ms;
If you wanted to check on the innings value, you could use:
WHERE mc.innings IS NULL
Also note the use of meaningful table aliases. Do not use arbitrary letters for represent tables. Use table abbreviations!

Excluding a value when null is present in the column

I want to filter the table without the row c
column 1
column 2
a
100
b
200
c
50
null
200
Desired output
column 1
column 2
a
100
b
200
null
200
I tried
select *
from table
where column1 <> 'c'
But since I can compare with null, I'm getting the wrong output. How do I deal with this?
You need to handle the null as follows:
select * from table where column1 <> 'c' or column1 is null
Or you can use the coalesce function as follows:
select * from table where coalesce(column1,'cc') <> 'c'
Coalesce will replace the null value in column1 with the value provided as the second argument. I have used the value which is not equal to 'c' so records with column1 as null will pass this condition
ANSI SQL, DISTINCT predicate.
select *
from table
where column1 is distinct from 'c'
However, not supported by all dbms products.

Impala SQL, return value if a string exists within a subset of values

I have a table where the id field (not a primary key) contains either 1 or null. Over the past several years, any given part could have been entered multiple times with one, or both of these possible options.
I'm trying to write a statement that will return some value if there is ever a 1 associated with the select statement. There are lots of semi-duplicate rows, some with 1 and some with null, but if there is ever a 1, I want to return true, and if there are only null values, I want to return false. I'm not sure how to code this though.
If this is my SELECT part,id from table where part = "ABC1234" statement
part id
ABC1234 1
ABC1234 null
ABC1234 null
ABC1234 null
ABC1234 1
I want to write a statement that returns true, because 1 exists in at least one of these rows.
The closest I've come to this is by using a CASE statement, but I'm not quite there yet:
SELECT
a1.part part,
CASE WHEN a2.id is not null
THEN
'true'
ELSE
'false'
END AS id
from table.parts a1, table.ids a2 where a1.part = "ABC1234" and a1.key = a2.key;
I also tried the following case:
CASE WHEN exists
(SELECT id from table.ids where id = 1)
THEN
but I got the error subqueries are not supported in the select list
For the above SELECT statement, how do I return 1 single line that reads:
part id
ABC1234 true
You can use conditional aggregation to check if a part has atleast one row with id=1.
SELECT part,'True' id
from parts
group by part
having count(case when id = 1 then 1 end) >= 1
To return false when the id's are all nulls use
select part, case when id_true>=1 then 'True'
when id_false>=1 and id_true=0 then 'False' end id
from (
SELECT part,
count(case when id = 1 then 1 end) id_true,
count(case when id is null then 1 end) id_false,
from parts
group by part) t

Hiding a row in a table with a query when 3 columns have null values

I am looking for the best way to build a query which would hide the record (row) in the event that three field values (in three different columns) would be null. The code below is giving me a syntax run time error message of 3075. Also, I am not sure if it is causing a problem but the code below is executed from a main form and impacting the subform frmStaticDataSkills02.
sql_get = "SELECT [tblCompetency02].[HighLevelObjective], [tblCompetency04].[Self], [tblCompetency04].[SelfSpecialLanguage], [tblCompetency04].[SelfChecklist], [tblCompetency04].[Team], [tblCompetency04].[TeamSpecialLanguage], [tblCompetency04].[TeamChecklist], [tblCompetency04].[Organisation], [tblCompetency04].[OrganisationSpecialLanguage], [tblCompetency04].[OrganisationChecklist], [tblCompetency02].[Competency] FROM [tblCompetency04] INNER JOIN [tblCompetency02] ON [tblCompetency04].[HighLevelObjective] = [tblCompetency02].[ID] WHERE ([tblcompetency04].[self]<>"" or [tblcompetency04].[team]<>"" or [tblcompetency04].[organisation]<>"")"
Form_frmStaticDataSkills02.Form.RecordSource = sql_get
In a general sense, in a table of N columns, you can explicitly count the number of NULL columns in a table and then add them up and compare the count of nulls to 3 in a where predicate:
SELECT *
FROM MyTable x
WHERE
((IIF(x.COL1 IS NULL, 1 , 0) +
IIF(x.COL2 IS NULL, 1 , 0) +
IIF(x.COL3 IS NULL, 1 , 0) +
IIF(x.COL4 IS NULL, 1 , 0))) <> 3;
(Obviously, keep adding IIF statements for all N columns of the table
This will return the data if not all three columns are NULL:
where not (col1 is null and col2 is null and col3 is null)
This is the same after applying algebra of logic: return the row if any of the three rows is NOT NULL
where col1 is not null or col2 is not null or col3 is not null)
End your query with:
WHERE [column_1] IS NOT NULL AND [column_2] IS NOT NULL AND [column_3] IS NOT NULL
You can do that in your where clause by specifying that all 3 fields should not be NULL, the result set that is returned will not have records where all 3 fields are NULL.
SELECT *
FROM tablename
WHERE
field1 IS NOT NULL AND
field2 IS NOT NULL AND
field3 IS NOT NULL
If you do not want to have rows returned where any one of the columns has null values you would use OR. For example:
SELECT *
FROM tablename
WHERE
field1 IS NOT NULL OR
field2 IS NOT NULL OR
field3 IS NOT NULL