SQL assign value for join purpose to null field without update - sql

With this sample data...
c1 c2 c3
10 a 10a
11 a **NULL**
12 a **NULL**
13 b 13b
13 b **NULL**
etc..
I want to assign c3 value to rows where it is NULL and c2 value is the same, but do not wish to actually update that value in table, only use it to join to another table while select runs.
I am able to do it using inner select and join, but I want to save as much processing power as possible because amount of data is huge and thought that some use of ISNULL or COALESCE should be able to do it, but I don't have enough experience to figure it on my own yet, or even say if it is possible. What do you think?

select
a.c1,
a.c2,
coalesce( a.c3, b.c3) as c3
from table1 a
left join table1 b
on a.c2 = b.c2
an a.c3 is null
and b.c3 is not null
this will work with the data that you have however if there is more than one row that is not null for c3 for a given c2 it will cause problems
If your DB supports max() over you can also do this
SELECT c1,
c2,
coalesce(c3, MAX(C3) over (partition by c2)) c3
from table1
demo

A sample pseudo code which i often use in my Query.
DECLARE #USER_ID AS VARCHAR(256)
SELECT #USER_ID = 'abc'
select *
from CC
INNER JOIN adm_co_users CR_US WITH(NOLOCK) ON ISNULL(CR_US.original_userID,'') =
(CASE ISNULL(CC.Createdby,'') WHEN '' THEN #USER_ID
ELSE CC.Createdby END )

Related

fetch value from multiple table

I have a table t1:
c1 c2
1 a
2 b
3 a
table t2:
c3 c4
4 1
5 2
6 3
I am writing a procedure:
select c1 from t1 where c2 = 'a';
which will give multiple outputs. Use that output (1,3)
select c3 from t2 where c4 = 1,
select c3 from t2 where c4 = 3 -- out put of first query;
How do I implement it ? Should i use any loops? If so, how do I loop or how do I write a procedure which returns the result of it?
you can use join
select c1,c3 from t1
inner join t2 on t1.c1=t2.c4
where c2='a'
You might have to work more on it but this is how i think this can be implemented.Inside the SP create a table data type where you can insert the multiple values fetched and then you can pass these values to another SP as a table value parameters where you can do the rest of the operations.
You can use in
select c3 from t2 where c4 in
(select c1 from t1 where c2 = 'a')
select c1,c3 from t1,t2
where t1.c1=t2.c4 and c2='a'

Return differing rows in tsql

I apologize for the basic non specific title. I can’t conceptualize how to ask this question or write the query I need in tsql. Any suggestions or guidance would be helpful. I have four columns that matter to me in a table:
c1(primarykey), c2, c3, c4
For any two rows, If c3 and c4 match but c2 doesn’t I want to return the rows. Amplify this to the entire table.
I’ve tried joining on a temp table then finding the difference through a left join on the table to itself but maybe I’m doing something incorrectly. Thank you in advance.
You could use:
WITH cte AS (
SELECT *, MIN(c2) OVER(PARTITION BY c3,c4) AS m, MAX(c2) OVER(PARTITION BY c3,c4) AS m2
FROM tab
)
SELECT *
FROM cte
WHERE m <> m2;
If you want to return the rows, then exists is a good way to go:
select t
from t
where exists (select 1
from t t2
where t2.c3 = t.c3 and t2.c4 = t.c4 and
t2.c2 <> t.c2
);
You do not mention NULL values in your question. If you have NULL values in any of the three columns, you would need to tweak the logic.
If you just wanted the c3/c4 pairs with different c2 values, you can use aggregation:
select c3, c4
from t
group by c3, c4
having min(c2) <> max(c2);
Finally, if you wanted to see pairs of non-matches on a single row, then:
select t.*, t2.c1, t2.c2
from t join
t t2
on t2.c3 = t.c3 and t2.c4 = t.c4 and
t2.c2 > t.c1;
With EXISTS:
select t.* from tablename t
where exists (
select 1 from tablename
where c2 <> t.c2 and c3 = t.c3 and c4 = t.c4
)
You can use Except
SELECT C1,C2,C3,C4 FROM TABLE1
EXCEPT
SELECT C4,C3,C2,C1 FROM TABLE1
This will check all the column values and if any of the value doesn't match then that record will be returns. More over you can add more columns to this query to match values.

Comma Separated list of rows of a column with group by on other columns

Below is the structure of table I have: -
Table T1
C1 C2 C3
----------
X P A
X P B
Y Q C
Y Q D
Desired output: -
C1 C2 C3
------------
X P A,B
Y Q C,D
Note: - I know i can do the same with For XML('') with group by on C1 and C2, but the main problem in my case is that the table T1 here must be a physical table object (either permanent or temp or table var or CTE) in DB. But in my case it's a derived table and when i am using the below query it's saying invalid object.
In my case it's not good to replace the derived table with temp# tables or fixed tables or even with CTE or table variable because it will take a great effort.
SELECT
b.C1, b.C2, Stuff((',' + a.C3 from t1 a where a.c1 = b.c1 for XML PATH('')),1,1,'') FROM
T1 b group by b.c1,b.c2
I did not have T1 as fixed table. Please consider it as derived table only.
I need the solution with existing derived table.
Please help.
Below is the query with derived table: -
Please consider this only as a demo query. It's not as simple as given below and a lot of calculations have done to get the derived tables and 4 levels of derived tables have been used.
SELECT C1, C2, Stuff((',' + a.C3 from A B where a.c1 = b.c1 for XML PATH('')),1,1,'')
FROM
(
SELECT C1, C2, C3 FROM T1 WHERE C1 IS NOT NULL--and a lot of calculation also
)A
Please mind that T1 is not just below one step, in my case T1 the actual physical table is 4 level downs by derived tables.
If you can post the query the produces derived table, we can help you work it out, but as of the moment try substituting table1 with the derived query.
;WITH Table1
AS
(
SELECT C1, C2, C3 FROM T1 WHERE C1 IS NOT NULL--and a lot of calculation also
)
SELECT
C1,C2,
STUFF(
(SELECT ',' + C3
FROM Table1
WHERE C1 = a.C1 AND C2 = a.C2
FOR XML PATH (''))
, 1, 1, '') AS NamesList
FROM Table1 AS a
GROUP BY C1,C2
SQLFiddle Demo

Access SQL Query to search value in 2 tables but use just one?

I have 2 tables in MS Access and need to query them looking for a value. If the value is in A, then use that. If value is in B, then use that. If the value is in both tables, then use only the value from table A.
How can I make a query to do that?
Thanks!
How about:
SELECT IIF(IsNull(AField),(SELECT AField FROM Table2 WHERE ID=16), AField)
FROM Table1
WHERE ID=16
If you want to do an entire table rather than 1 row :-
select C1, C2 from TableA where C2 is not null
union all
select C1, C2 from TableB where C1 in ( select c1 from TableA where C2 is null )

Update duplicate columns table with join

I am having a problem for Oracle update SQL with join. I have a table A which has 5 columns (C1, C2, C3, C4, C5); table B which has 3 columns (D1, D2, D3). For table A, I only use 2 columns (C2, C3) to join table B (D1, D2), and update table A column C2 with table B column D3.
For table A, it will be lots of duplicates for both C2 and C3; but for condition C4 as 10, there will be no duplicates which is what I want to update.
For example, table A has records as:
1,100,1500,10,'ORG'
1,200,2000,10,'ORG'
1,300,2500,10,'ORG'
2,1000,500,20,'PERSON'
2,1000,200,20,'PERSON'
2,2000,200,20,'PERSON'
You can see that for C4 as 10, there is no duplicate for C2 and C3. But for C4 as 20, there will be duplicates for C2 and C3.
For table B, it will be like
100,1500,80
200,2000,100
300,3000,200
There is no duplicates for table B, and will join B with A as A.C2 = B.D1 and A.C3 = B.D2 to update A.C2 to B.D3.
I only have to update C4=10 records to join with table B based on B.D1 and B.D2.
I have SQL as below, but failed as
ORA-01779: cannot modify a column
which maps to a non key-preserved
table
Can anyone tell me what is wrong with my SQL?
UPDATE (
SELECT A.C2 OID, B.D3 TID FROM A, B
WHERE A.C2 = B.D1 AND A.C3 = B.D2 AND A.C4=10 AND B.D3 <> ' ' )
SET OID = TID
Thanks a lot!
Can't you use an update statement like...
UPDATE A
set c2 = (select D3
from B
where B.D2 <> ' ' and
A.C2 = b.D1 and A.C3=B.D2)
)
where A.C4=10
Also, your question and the problem description itself looks like a puzzle thtis very hard to understand.
Can you post some data and create table statements so that it's easy to reproduce your case ?(from next time maybe....)
First, it sounds like you are trying to update TableA. Second, the official ANSI specification for the Update statement does not provide for a join directly in the statement (you can have joins only through subqueries). One reason is that it would create ambiguities when duplicate rows were involved. So, you might try something like:
Update A
Set OID = (
Select B.D3
From B
Where B.D1 = A.C2
And B.D2 = A.C3
And B.D3 Is Not Null
)
Where A.C4 = 10
And Exists (
Select 1
From B
Where B.D1 = A.C2
And B.D2 = A.C3
And B.D3 Is Not Null
)
UPDATE A
SET C2 = (
SELECT B.D3
FROM B
WHERE A.C2 = B.D1 AND A.C3 = B.D2)
WHERE A.C4=10
AND EXISTS (
SELECT *
FROM B2
WHERE A.C2 = B2.D1 AND A.C3 = B2.D2)
No need to alias for update statements. Also you have the condition on B.D2 <> ' ' and also A.C3 = B.D2, so it is just as easy to just filter on A.C3 <> ' ', since A is the target table. If A.C3 is never blank, then the condition is not even required.