How to make a new column in SELECT clause and fill it with a string/list dynamically with concat of all condition statements satisfied? - sql

So there are two tables in a database. I have to find out whichever rows have discrepancy based on certain conditions (in couple of cases that's just equality checking between fields). I report ID of those rows.
The problem is to also include the reasons in another column as to why that ID is reported. Because an id can be fail multiple conditions (like mismatch on two fields), I just wanted to include all of those reasons in another column.
Basic idea is to append all the mismatches in another column.
I've looked at several SO questions but they don't exactly my use case. So now I'm thinking it's not possible with SQL.
I searched Google for "enter dynamic column values based on conditions sql", and hit : SQL Conditional column data return in a select statement : This adds a static column
I also learned it's possible to add another column in SELECT with dynamic content like this:
SELECT id, CASE
WHEN columnname "DEF" then "I" ELSE "YOU" newColumnName
FROM tableName
But I have not been able to find dynamic column value assignment and update SQL. That's the problem.
Expected results:
I just want to be able to concat all the cases "strings" which a record is applicable for.
Do this with the two tables.
So because I have two tables to work with I have to put these conditions in the WHERE sub-clause, and not in the SELECT one.
So, if for ID = 345, column "FOO_MAN" does not match between two tables, and column "BAR_TOO" also does not match between two tables, then?
Then I want my select clause to capture information like this:
ID | REASON
345 | FOO_MAN BAR_TWO

It's probably easier to build this type of query dynamically (e.g. using a stored procedure) based on the conditions you want to test, but here is a small example which shows how it can be done:
SELECT t1.id,
CONCAT_WS(' ',
CASE WHEN t1.foo != t2.foo THEN 'foo' END,
CASE WHEN t1.bar != t2.bar THEN 'bar' END
) AS reason
FROM t1
JOIN t2 ON t2.id = t1.id
WHERE t1.foo != t2.foo OR t1.bar != t2.bar
Output (for my demo on dbfiddle)
id reason
2 foo
4 bar
5 foo bar

Related

Compare one value of column A with all the values of column B in Hive HQL

I have two columns in one table say Column A and Column B. I need to search each value of Column A with All the values of column B each and every time and return true if the column A value is found in any of the rows of column B. How can i get this?
I have tried using the below command:
select column _A, column_B,(if (column_A =column_B), True, False) as test from sample;
If i use the above command, it is checking for that particular row alone. But I need true value, if a value of column A is found in any of the rows of column B.
How can i can check one value of column A with all the all the values of column B?
Or Is there any possibility to iterate and compare each value between two columns?
Solution
create temporary table t as select rand() as id, column_A, column_B from sample; --> Refer 1
select distinct t3.id,t3.column_A,t3.column_B,t3.match from ( --> Refer 3
select t1.id as id, t1.column_A as column_A, t1.column_B as column_B,--> Refer 2
if(t2.column_B is null, False, True) as match from t t1 LEFT OUTER JOIN
t t2 ON t1.column_A = t2.column_B
) t3;
Explanation
Create an identifier column to keep track of the rows in original table. I am using rand() here. We will take advantage of this to get the original rows in Step 3. Creating a temporary table t here for simplicity in next steps.
Use a LEFT OUTER JOIN with self to do your test that requires matching each column with another across all rows, yielding the match column. Note that here multiple duplicate rows may get created than in Sample table, but we have got a handle on the duplicates, since the id column for them will be same.
In this step, we apply distinct to get the original rows as in Sample table. You can then ditch the id column.
Notes
Self joins are costly in terms of performance, but this is unavoidable for solution to the question.
The distinct used in Step 3, is costly too. A more performant approach would be to use Window functions where we can partition by the id and pick the first row in the window. You can explore that.
You can do a left join to itself and check if the column key is null. If it is null, then that value is not found in the other table. Use if or "case when" function to check if it is null or not.
Select t1.column_A,
t1.column_B,
IF(t2.column_B is null, 'False', 'True') as test
from Sample t1
Left Join Sample t2
On t1.column_A = t2.column_B;

Compare tables and Find the missing records

I am trying to compare a table T1 and a view v1 and find the missing records from the table T1 and display the results in a excel when a button is clicked. I am trying the wrap up the situation into a stored procedure and call it from vba code. I am not sure on how to start this.. The field names are different in both the tables, although it has same data. Any help will be much appreciated. I have tried many code samples , but I didn't achieve what I want..
Table T1
alpha.FileID
Master Policy Number
Insurance Name
View V1
FileID
PolNO
InsName
These are the few columns. Though, they have different field names, the data are the same. Some times the records are missing in the table v1, and I need to compare the two tables and find the missing records of the table v2.
SELECT View_v1.[Insured Name]
FROM View_v1
WHERE View_v1.alpha.FileID NOT IN
(
SELECT Table_t1.FileID
FROM Table_t1
)
An except clause is the easiest way to do this:
SELECT FileID, PolNO, InsName
FROM View V1
EXCEPT
SELECT FileID, MasterPolicyNumber, InsuranceName
FROM Table T1
This will give you the rows in the first select that do not exist in the second select (depending on your desired results you might flip the top and bottom selects). As long as the data types and number of columns are the same, the name of each field doesn't matter. Your result set will show the field names of the first select.
Also since you didn't specify your dbms, "MINUS" is used instead of "EXCEPT" for some dbms's like Oracle.
I believe this is what you're looking for based on your description.
I'm comparing every field, not just FileID as your example appears to be attempting. So, if you truly want to look only for missing FileIDs, just remove the other join on conditions.
SELECT View_v1.FileID, View_v1.PolNO, View_v1.InsName
FROM View_v1
LEFT JOIN Table_t1
on View_v1.FileID = Table_t1.FileID
and View_v1.PolNO = Table_t1.[Master Policy Number]
and View_v1.InsName = Table_t1.[Insurance Name]
WHERE Table_t1.FileID is null

Compare comma separated list with individual row in table

I have to compare comma separated values with a column in the table and find out which values are not in database. [kind of master data validation]. Please have a look at the sample data below:
table data in database:
id name
1 abc
2 def
3 ghi
SQL part :
Here i am getting comma separated list like ('abc','def','ghi','xyz').
now xyz is invalid value, so i want to take that value and return it as output saying "invalid value".
It is possible if i split those value, take it in temp table, loop through each value and compare one by one.
but is there any other optimal way to do this ??
I'm sure if I got the question right, however, I would personally be trying to get to something like this:
SELECT
D.id,
CASE
WHEN B.Name IS NULL THEN D.name
ELSE "invalid value"
END
FROM
data AS D
INNER JOIN badNames B ON b.Name = d.Name
--as SQL is case insensitive, equal sign should work
There is one table with bad names or invalid values if You prefer. This can a temporary table as well - depending on usage (a black-listed words should be a table, ad hoc invalid values provided by a service should be temp table, etc.).
NOTE: The select above can be nested in a view, so the data remain as they were, yet you gain the correctness information. Otherwise I would create a cursor inside a function that would go through the select like the one above and alter the original data, if that is the goal...
It sounds like you just need a NOT EXISTS / LEFT JOIN, as in:
SELECT tmp.InvalidValue
FROM dbo.HopeThisIsNotAWhileBasedSplit(#CSVlist) tmp
WHERE NOT EXISTS (
SELECT *
FROM dbo.Table tbl
WHERE tbl.Field = tmp.InvalidValue
);
Of course, depending on the size of the CSV list coming in, the number of rows in the table you are checking, and the style of splitter you are using, it might be better to dump the CSV to a temp table first (as you mentioned doing in the question).
Try following query:
SELECT SplitedValues.name,
CASE WHEN YourTable.Id IS NULL THEN 'invalid value' ELSE NULL END AS Result
FROM SplitedValues
LEFT JOIN yourTable ON SplitedValues.name = YourTable.name

Can I use a table column name as a search argument in db2 "like" or "contain" operator/function

I have two tables: one containing a column (Description) that I would like to search using values in a column (keyword) in another table. I would like to perform something like
select table1.description, tabl2.keyword,
case when
table1.description like `'''%'||table2.keyword||'%''' then 1
-- or contains(table1.description, table2.keyword)
else
0
end
as found
from table1, table2
The documentation for Contain function seems to indicate that the search parameter (table2.keyword in my case) has to be a constant (I suspect "like" also has similar constraints).
The error messages I get seem to indicate this constraint.
Is there a solution that I can use?
You can do it with like. Your query should work:
select table1.description, tabl2.keyword,
(case when table1.description like '''%'||table2.keyword||'%'''
then 1 else 0
end) as found
from table1 cross join table2;
I prefer explicit joins, cross join instead of ,.

SQL Server where column in where clause is null

Let's say that we have a table named Data with Id and Weather columns. Other columns in that table are not important to this problem. The Weather column can be null.
I want to display all rows where Weather fits a condition, but if there is a null value in weather then display null value.
My SQL so far:
SELECT *
FROM Data d
WHERE (d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%' OR d.Weather IS NULL)
My results are wrong, because that statement also shows values where Weather is null if condition is not correct (let's say that users mistyped wrong).
I found similar topic, but there I do not find appropriate answer.
SQL WHERE clause not returning rows when field has NULL value
Please help me out.
Your query is correct for the general task of treating NULLs as a match. If you wish to suppress NULLs when there are no other results, you can add an AND EXISTS ... condition to your query, like this:
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
OR (d.Weather IS NULL AND EXISTS (SELECT * FROM Data dd WHERE dd.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'))
The additional condition ensures that NULLs are treated as matches only if other matching records exist.
You can also use a common table expression to avoid duplicating the query, like this:
WITH cte (id, weather) AS
(
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
)
SELECT * FROM cte
UNION ALL
SELECT * FROM Data WHERE weather is NULL AND EXISTS (SELECT * FROM cte)
statement show also values where Wether is null if condition is not correct (let say that users typed wrong sunny).
This suggests that the constant 'sunny' is coming from end-user's input. If that is the case, you need to parameterize your query to avoid SQL injection attacks.