Update column with specific values ( if clause) - sql

I am trying to insert new values into specific column with "update table set specific column...."
I have two tables like this:
Table1
Name Idnumber Score
JOHN DB 10
JOHN IT NULL
KAL DB 9
HENRY KK 7
KAL DB 10
HENRY IP 9
ALI IG 10
ALI PA 9
Table2
NAME | MONEY |
-----------------|
JOHN | |
-----------------|
KAL | |
-----------------|
HENRY | |
-----------------|
ALI | |
-----------------
And I want that my table look like this:
Updated Table
NAME | MONEY |
-----------------|
JOHN | |
-----------------|
KAL | yes |
-----------------|
HENRY | half |
-----------------|
ALI | yes |
-----------------
The condition for writing "yes" into money column is that all scores under same name in table1 should be 9 or higher, the condition for writing "half" is that scores should be no lower than 6 ( what I mean is that scores might be 10,9,8,7 and 6)
So basically it means, that, for example, Henry cannot be selected and I cannot write "yes" next to his name in updated table, because he has score under the value of 9 in one line , but in the other he has the score of 7.(null values also should be emitted).
I'm using a sas program. Thank you!!!

You seem to be treated NULL as a value that is less than "9". In standard SQL (which works in both MySQL and SAS, the original tags) is:
update table2 t2
set money = 'YES'
where not exists (select 1
from table1 t1
where t1.name = t2.name and coalesce(t1.score, 0) < 9
);
If you want to guarantee that there is at least one row in table2, one method is aggregation:
update table2 t2
set money = 'YES'
where (select (case when sum(case when t1.score > 9 then 1 else 0 end) = count(*)
then count(*)
end)
from table1 t1
where t1.name = t2.name
) > 0

You could try the following syntax:
update table2
set money = 'YES'
where not exists (select 1 from table1 t1 where t1.name = table2.name and t1.score < 9)
However this would also update records that have no match in table1. In MySQL, one simple option to avoid that uses a join:
update table2 t2
inner join (select name, min(score) min_score from table1 group by name) t1
on t1.name = t.name and t1.min_score >= 9
set t2.money = 'YES'

Related

query select equaled data on three columns of table with four columns and ignore one

I have table have four columns like (right ,left ,up ,down) I want to build query that show equaled data on three of the four columns;
example:
| id | right | left | up | down |
|:---|:------:|:-----:|:------:| -----:|
| 1 | street |hospital|coffee |building|
| 2 | house |hospital|coffee |building|
| 3 | road | bus |coffee |sign |
| 4 | house |hospital|coffee |sign |
| 5 | car |road |coffee |sign |
the result should be like:
id
right
left
up
down
1
street
hospital
coffee
building
2
house
hospital
coffee
building
id number 3 and 5 not included because every column should equal it's self
is that query correct
select t.* from test_table t where
(t.right,t.left,t.up) in (select t.right,t.left,t.up from test_table t group by t.right,t.left,t.up having count(*)>1)
or (t.right,t.left,t.down) in (select t.right,t.left,t.down from test_table t group by t.right,t.left,t.down having count(*)>1)
or (t.right,t.up,t.down) in (select t.right,t.up,t.down from test_table t group by t.right,t.up,t.down having count(*)>1)
or (t.left,t.up,t.down) in (select t.left,t.up,t.down from test_table t group by t.left,t.up,t.down having count(*)>1)
and t.mud_id=285 order by t.right,t.left,t.up,t.down ;
if it correct it's go in loop without result for more than 10m waiting
if not
please what is the correct query to get the result
Since there are some assumptions to be made on how how to order and/or organize the results, you may use the query below to identify each matching pair.
DECLARE #T TABLE(ID INT, [right] VARCHAR(20), [left] varchar(20), up
varchar(20), down varchar(20))
INSERT INTO #T VALUES
(1,'street','hospital','coffee','building'),
(2,'house','hospital','coffee','building'),
(3,'road','bus','coffee','sign'),
(4,'house','hospital','coffee','sign'),
(5,'car','road','coffee','sign'),
(6,'street','road','coffee','sign')
SELECT
T1.ID AS MatchID1,
T2.ID AS MatchID2
FROM
#T T1
INNER JOIN #T T2 ON T1.ID <> T2.ID
GROUP BY
T1.ID, T2.ID
HAVING
MAX(CASE WHEN T1.[right] = T2.[right] THEN 1 ELSE 0 END +
CASE WHEN T1.[left] = T2.[left] THEN 1 ELSE 0 END +
CASE WHEN T1.up = T2.up THEN 1 ELSE 0 END +
CASE WHEN T1.down = T2.down THEN 1 ELSE 0 END) = 3
MatchID1 MatchID2
2 1
1 2
4 2
2 4
6 5
5 6
A trick to bring back matches by first occurrence using:
INNER JOIN #T T2 ON T1.ID > T2.ID
MatchID1 MatchID2
1 2
2 4
5 6

SQL - How to pick the best available value for each column for each ID from multiple tables?

I have two tables with the same variables referring to attributes of a person.
How can I combine data from two such tables picking the best available value for each column from each table for each field?
Requirements:
For each field, I would like to fill it with a value from either one of the tables, giving a preference to table 1.
Values can be NULL in either table
In the combined table, the value for column 1 could come from table 2 (in case table 1 is missing a value for that person) and the value for column 2 could from table 1 (because both tables had a value, but the value from table 1 is preferred).
In my real example, I have many columns, so an elegant solution with less code duplication would be preferred.
Some users may exist in only one of the tables.
Example:
Table 1:
user_id | age | income
1 | NULL| 58000
2 | 22 | 60000
4 | 19 | 35000
Table 2:
user_id | age | income
1 | 55 | 55000
2 | 19 | NULL
3 | 22 | 33200
Desired output:
user_id | age | income
1 | 55 | 58000
2 | 22 | 60000
3 | 22 | 33200
4 | 19 | 35000
I think that's a full join and priorization logic with colaesce():
select user_id,
coalesce(t1.age, t2.age) as age,
coalesce(t1.income, t2.income) as income
from table1 t1
full join table2 t2 using(user_id)
Use full outer join if user_id in each table is unique.
SELECT
COALESCE(t1.user_id, t2.user_id) AS user_id,
GREATEST(t1.age, t2.age) AS age,
GREATEST(t1.income, t2.income) AS income
FROM t1
FULL OUTER JOIN t2 ON t1.user_id = t2.user_id
try like below using coalesce()
select t1.user_id, coalesce(t1.age,t2.age),
t1.income>t2.income then t1.income else t2.income end as income
table1 t1 join table2 t2 on t1.usesr_id=t2.user_id
You can use below code:
With TableA(Id,age,income) as
( --Select Common Data
select table_1.id,
--Select MAX AGE
case
when table_1.age> table_2.age or table_2.age is null then table_1.age else table_2.age
end,
--Select MAX Income
case
when table_1.income>table_2.income or table_2.income is null then table_1.income else table_2.income
end
from table_1 inner join table_2 on table_2.id=table_1.id
union all
-- Select Specific Data of Table 2
select table_2.id,table_2.age,table_2.income
from table_2
where table_2.id not in (select table_1.id from table_1)
union all
-- Select Specific Data of Table 1
select table_1.id,table_1.age,table_1.income
from table_1
where table_1.id not in (select table_2.id from table_2)
)select * from TableA

Update a table based on a condition

I have a column Table1.Tradedate and another column Table2.SettlementDate.
Based on the comparison between these 2, I want to update a column in table 2
IF (Table1.TradeDate <= Table2.SettlementDate)
BEGIN
UPDATE Table2 SET Status='Y'
END
This is what I have tried but I know its wrong, since the table will obviously contain more than 1 records. So, I believe what I should do is
use a join on 2 tables based on some #id to pick a particular record
check the IF condition for that particular record
update the Status column in table2.
I hope my approach is correct but I am writing it incorrectly.
Table1:
SKacc | Name | TradeDate | Othercolumns....
1 | xxx | 01/07/2019 |
2 | xxx | 01/06/2019 |
Table2:
SKAcc | Name | SettlementDate | Status |Other Columns....
1 | xxx | 01/08/2019 | NULL |
2 | xxx | 01/08/2019 | NULL |
Try below
update t2 set Status = 'Y'
from table2 t2
join table1 t1 on t1.id = t2.id
where t1.tradeDate <= t2.settlementDate
Try joining the two tables with the related column and then update the table you want to update with the value. Using inner join in the example but can change depending on the usecase
UPDATE Table2
SET Status = 'Y'
FROM Table2
INNER JOIN Table1 ON Table1.id = Table2.table1_id
WHERE Table1.TradeDate <= Table2.SettlementDate
I would not recommend a JOIN for this purpose. Instead:
update table2
set Status = 'Y'
where exists (select 1
from table1 t1
where t1.id = t2.id and
t1.tradeDate <= t2.settlementDate
);
The reason I recommend this version is because you have not specified that id is unique in table1. In general, you only want to use JOIN in UPDATE when you can guarantee that there is only one matching row.

MS SQL Where one column is x or y and both returned

I have a table as follows with dates in. The table has many more records but simplified for asking purposes:
Name | Date | Grade
Person 1 | 01-01-2001 | B
Person 1 | 31-01-2001 | A
Person 2 | 01-01-2001 | C
Person 3 | 31-01-2001 | A
I want to return both records for Person 1 but not either of the other two. AND returns nothing obviously and OR returns everything. I want to search on the date not the grade or the person.
So the result would be:
Name | Date | Grade
Person 1 | 01-01-2001 | B
Person 1 | 31-01-2001 | A
One simple way to handle this is to aggregate by person and then assert that the two dates of interest are both present:
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT Name
FROM yourTable
WHERE Date IN ('2001-01-01', '2001-01-31')
GROUP BY Name
HAVING COUNT(DISTINCT Date) = 2
) t2
ON t1.Name = t2.Name
You can uses EXISTS to return a row if there exists another row with that name, having the other A/B grade.
select t1.*
from tablename t1
where t1.Date in ('2001-01-01', '2001-01-31')
and exists (select 1 from tablename t2
where t2.Name = t1.Name
and t2.Date in ('2001-01-01', '2001-01-31')
and t2.Date <> t1.Date)

Select date from table with new column as result from other table

In SQL Server 2008, how can I retrieve data from table1 with new magic column (bit value), this new column take 'true' if current id from table1 exist in table2, else take 'false'.
For example :
Table1
id | name
-----------
10 | USA
11 | UK
12 | France
table2
id | title | fk
----------------------
1 | v1 | 10
2 | v2 | 10
3 | v3 | 11
result :
id | name | new column
----------------------------
10 | USA | true
11 | UK | true
12 | France | false
SELECT DISTINCT table1.id, table1.name,
CASE WHEN table2.id IS NULL THEN 'False' ELSE 'True' END AS mycolumn
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.fk
You can use left join to get the data you want.
SQL
select A.*
,case when B.fk is not null then 'true' else 'false' end as [new column]
from table1 A
left join
(
select distinct fk from table2
)B on A.id=B.fk
OUTPUT
id name new column
10 USA true
11 UK true
12 France false
Read about different join types. this is basic SQL.
SELECT Table1.[id], [name], CASE WHEN Table2.[id] IS NULL THEN 0 ELSE 1 END As [New column]
FROM Table1 LEFT JOIN
Table2 ON(Table1.[id] = Table2.[fk])
The following query returns the expected result:
SELECT T1.*
,CAST(CASE
WHEN T2.id IS NOT NULL THEN 1
ELSE 0
END AS BIT) AS magic_column
FROM table1 T1
LEFT JOIN table2 T2 ON T1.id = T2.fk