How to join three tables with to avoid invalid identifier error - sql

Having three tables as follows
Table 1
c_id User_id code
-------------------------
001 UI1 AB01
002 UI2 XD01
003 UI3 AD01
004 UI4 OP01
005 UI5 QW01
Table 2
id c_id brn_code sts
-----------------------------------
1 004 90E1 Y
2 005 91E3 Y
3 001 91S4 Y
4 003 93S6 Y
5 002 99S7 Y
Table 3
Key brn_code
--------------------
1 91S4
2 90D1
3 90Z5
4 93S6
5 96W4
Need Output like below
INSERT INTO table2 t2 (c_id, brn_code, sts)VALUES ('004', '90D1', 'Y');
INSERT INTO table2 t2 (c_id, brn_code, sts)VALUES ('004', '90Z5', 'Y');
INSERT INTO table2 t2 (c_id, brn_code, sts)VALUES ('004', '96W4', 'Y');
Wrote query as
SELECT 'INSERT INTO table2 t2 (c_id, brn_code, sts)VALUES ('||t1.c_id||', '||t3.brn_code||', '||''''||'Y'||''''||');'
FROM Table 1 t1 JOIN Table 2 t2
ON t1.c_id = t2.c_id JOIN
(SELECT brn_code FROM Table 3 t3
MINUS
(SELECT brn_code FROM Table 2 t2
WHERE t2.c_id IN (SELECT t1.c_id FROM Table 1 t1 WHERE t1.User_id = 'UI4' AND t1.code = 'OP01')
AND t2.sts = 'Y')) ON t2.brn_code = t3.brn_code;
For above query i returns error as invalid identifier. I don't know why this error came.
How to get output as above.

If you really wrote Table 1 t1 etc., that's certainly wrong. Should probably be something like Table1 if your tables are called as suggested in your first line.

You have problem with names of the table as already mentioned in the other answer.
Also, you can simplify your query by using EXISTS as follows:
SELECT 'INSERT INTO table2 t2 (c_id, brn_code, sts)VALUES ('||t1.c_id||', '||t3.brn_code||', '||''''||'Y'||''''||');'
FROM Table1 t1 JOIN Table2 t2 ON t1.c_id = t2.c_id
JOIN table3 t3 on t2.brn_code = t3.brn_code
Where not exists (
Select 1 from table2 t22 join table1 t11 on t11.c_id = t22.c_id
Where t11.User_id = 'UI4' AND t11.code = 'OP01' AND t22.sts = 'Y' And t3.brn_code = t22.brn_code);

Related

prefer table 3 over table 2 and table 2 over table 1

I have 3 tables with names and number of few of my friends.
Table 3 has correct data, table 2 has minute errors in data and table 1 has more than table 2.
if a user exists in table 2 and 3 then show table 3 details in output else table 2 details, if user is not even there in table 2 then show user data from table1.
more like a preference order.
DUMMY DATA:
table 1 :
name phone
abc 2343
bcd 3434
ccd 3455
ffc 4545
table 2 :
name phone
abc 2313
bcd 3414
ccd 3415
table 3 :
name phone
abc 2344
bcd 3431
expected output :
name phone
abc 2344
bcd 3431
ccd 3415
ffc 4545
I tried this query but unable to find correct output.
select phone,
coalesce(table1.name, TABLE2.name,TABLE3.name) as namee
FROM TABLE1
left JOIN TABLE2
ON table1.name = table2.name
INNER JOIN table3
ON table3.name = table2.name
Would be a huge, huge heeelppppp.
Gordon was close; he had the preference backwards. Please make sure you understand why the script works.
-- grab all our preferred data first
select t3.*
from table3 t3
union all
-- grab anything that doesn't exist in our preferred table
select t2.*
from table2 t2
where not exists (select 1 from table3 t3 where t3.name = t2.name)
union all
-- grab anything that doesn't exist in our preferred tables
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.name = t1.name) and
not exists (select 1 from table3 t3 where t3.name = t1.name);
Use union all:
select t1.*
from table1 t1
union all
select t2.*
from table2 t2
where not exists (select 1 from table1 t1 where t1.name = t2.name)
union all
select t3.*
from table3 t3
where not exists (select 1 from table1 t1 where t1.name = t3.name) and
not exists (select 1 from table2 t2 where t2.name = t3.name);

Update table if join table does not have rows

I have two tables which has relationships and I trying to update base table if there are no records in the child table.
Table1:
id value
1 abc
2 xyz
Table2:
id table1_id
1 1
2 1
So in this case I want to update table1 id 2 to pqr as it does not have associated rows in table2. For id 1 nothing happens.
I tried this way but this is completely wrong
update table1 set value = 'pqr'
from table1 t1 inner join table2 t2 on count(t2.table1_id) < 1
If you want to update the rows of table1 with ids that don't have a match in table2 in the column table1_id then you can do it with a LEFT JOIN and update the unmatched rows:
update t1
set t1.value = 'pqr'
from table1 t1 left join table2 t2
on t2.table1_id = t1.id
where t2.table1_id is null
See the demo.
Results:
> id | value
> -: | :----
> 1 | abc
> 2 | pqr
I believe you're looking for WHERE NOT EXISTS.
update table1
set value = 'pqr'
from table1 t1
WHERE
NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.table1_id = t1.id);
Although this assumes you're asking the question in the title, not the one in the test of your question.
UPDATE table1
SET value = 'pqr'
WHERE id IN (SELECT t1.id FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.table1_id)

SQL Query -Without using nested subqueries

Table1
ID SystemID Description
---------------------------
1 25 Test1
1 25 Test2
2 40 Test1
2 40 Test3
3 26 Test9
3 36 Test5
4 70 Test2
4 70 Test9
Table2
ID Department
------------------
1 Sales
2 Marketing
3 Accounting
4 Purchasing
I have these 2 tables, Table1 and Table2.
I need to select all the distinct ids from Table1 that have the same description as ID = 1 and SystemID = 25, and then select all the rows from Table2 from the query result.
Is there a better way to query for this, without using nested subqueries?
select *
from Table2
where ID in (select distinct(ID)
from Table1
where SystemID = 25
and Description in (select Description
from Table1
where ID = 1 and SystemID = 25))
Final output is
1 Sales
2 Marketing
4 Purchasing
Any help is appreciated. Thank you.
I think you want:
select t1.id, t2.department
from table1 t1 join
table2 t2
on t1.id = t2.id
where t1.description in (select tt1.description from table1 tt1 where tt1.id = 1 and tt1.systemid = 25);
This is standard SQL and should work in both SQL Server and Oracle.
You can also use a modification of an outer join to detect presence of a value.
SELECT DISTINCT t2.ID, t2.DEPARTMENT
FROM
table2 AS t2
INNER JOIN table1 AS t1a ON table2.ID = table1.ID
LEFT OUTER JOIN table1 AS t1b ON t1b.id = 1 AND t1b.systemID = 25 AND t1b.description = t1a.description
WHERE t1b.ID IS NOT NULL
AND t1a.systemID = 25
This will filter out all entries who don't have a description matching an entry with id 1 and systemID 25
I believe this should give you the same result. Instead of using an IN I used an EXISTS and then instead of a futher subquery you can then use a JOIN:
SELECT *
FROM Table2 T2
WHERE EXISTS (SELECT 1
FROM Table1 T1
JOIN Table1 T1t ON T1.[Description] = T1t.[Description]
WHERE T1.ID = T2.ID
AND T1t.ID = 1 AND T1t.SystemID = 25);
SELECT DISTINCT T2.* --Use a distinct for simplicity but a group by is better
FROM Table2 AS T2
INNER JOIN Table1 AS T1_Source ON T1_Source.SystemID = 25 AND T1_Source.ID = 1
/*^ Find table1 with System and ID
Expected Result
ID SystemID Description
1 25 Test1
1 25 Test2
Note Rows are duplicated use distinct or group by
*/
INNER JOIN Table1 AS T1_Target ON T1_Target.Description = T1_Source.Description
/*^ Find table1 with all the Description matching the result we found
Expected Result
ID SystemID Description
1 25 Test1
1 25 Test2
2 40 Test1
4 70 Test2
Note Rows are duplicated use distinct or group by
*/

Aggregate functions as column results from multiple tables

I have the following table structures:
Table1
--------------
Table1Id
Field1
Field2
Table2
------------
Table2Id
Table1Id
Field1
Field2
Table3
-----------
Table3Id
Table1Id
Field1
Field2
I need to be able to select all fields in Table1, count of records in Table2, and count of records in Table3 Where count of records in Table2 > count of records in Table3
Here is an example of expected output with the given data:
Table1 Data
-------------
1 Record1Field1 Record1Feild2
2 Record2Field1 Record2Feild2
3 Record3Field1 Record3Feild2
4 Record4Field1 Record4Feild2
Table2 Data
------------
1 1 Record1Field1 Record1Feild2
2 1 Record2Field1 Record2Feild2
3 2 Record3Field1 Record3Feild2
4 2 Record4Field1 Record4Feild2
5 2 Record5Field1 Record5Feild2
6 4 Record6Field1 Record6Feild2
7 4 Record6Field1 Record6Feild2
8 4 Record6Field1 Record6Feild2
Table3 Data
------------
1 2 Record1Field1 Record1Feild2
2 2 Record2Field1 Record2Feild2
3 3 Record3Field1 Record3Feild2
4 3 Record4Field1 Record4Feild2
5 3 Record5Field1 Record5Feild2
6 4 Record6Field1 Record6Feild2
Desired Results
Table1Id Field1 Field2 Table2Count Table3Count
1 Record1Field1 Record1Field2 2 0
2 Record2Field1 Recird2Field2 3 2
4 Record4Field1 Recird4Field2 3 1
Notice record 3 in Table 1 is not shown because the record count in Table2 is less than the record count in Table3. I was able to make this work using a very ugly query similar to the one below but feel there is a much better way to do this using joins.
SELECT
t1.Table1Id,
t1.Field1,
t1.Field2
(Select Count(Table2Id) From Table2 t2 Where t2.Table1Id = t1.Table1Id) as Table2Count,
(Select Count(Table3Id) From Table3 t3 Where t3.Table1Id = t1.Table1Id) as Table3Count,
From
Table1 t1
Where
(Select Count(Table2Id) From Table2 t2 Where t2.Table1Id = t1.Table1Id) > (Select Count(Table3Id) From Table3 t3 Where t3.Table1Id = t1.Table1Id)
Hard to test it without working examples but something along these lines should be a good starting point.
SELECT
t1.Table1Id,
t1.Field1,
t1.Field2,
COUNT(DISTINCT t2.Table2Id),
COUNT(DISTINCT t3.Table3Id)
From Table1 t1
LEFT OUTER JOIN Table2 t2 ON t1.Table1Id = t2.Table1Id
LEFT OUTER JOIN Table3 t3 ON t1.Table1Id = t3.Table1Id
GROUP BY t1.Table1Id
HAVING COUNT(DISTINCT t2.Table2Id) > COUNT(DISTINCT t3.Table3Id)
You could get all the value in t1 and the data form t2 e t3 for your comparision using a couple of join on grouped values
SELECT
t1.Table1Id
,t1.Field1
,t1.Field2
, tt2.count_t2
, tt3.count_t3
from table1 t1
join (
select Table1Id, count(*) count_t2
From Table2
group by Table1Id
) tt2 on tt2.Table1Id = t1.Table1Id
join (
select Table1Id, count(*) count_t3
From Table3
group by Table1Id
) tt3 on tt3.Table1Id = t1.Table1Id
where tt2.count_t2 < tt3.count_t3 <

Get groups that are exactly equal to a table

I have a query that groups easily. I need to get the groups that have exactly the same records to another table (relationship).
I'm using ANSI-SQL under SQL Server, but I accept an answer of any implementation.
For example:
Table1:
Id | Value
---+------
1 | 1
1 | 2
1 | 3
2 | 4
3 | 2
4 | 3
Table2:
Value | ...
------+------
1 | ...
2 | ...
3 | ...
In my example, the result is:
Id |
---+
1 |
How imagined that it could be the code:
SELECT Table1.Id
FROM Table1
GROUP BY Table1.Id
HAVING ...? -- The group that has exactly the same elements of Table2
Thanks in advance!
You can try the following:
select t1.Id
from Table2 t2
join Table1 t1 on t1.value = t2.value
group by t1.Id
having count(distinct t1.value) = (select count(*) from Table2)
SQLFiddle
To get the same sets use an inner join:
SELECT Table1.Id
FROM Table1
INNER JOIN table2 ON table1.id=table2.id
GROUP BY Table1.Id
HAVING ...? --
CREATE TABLE #T1 (ID INT , [Values] INT) INSERT INTO #T1 VALUES (1,1),(1,2),(1,3),(2,4),(2,5),(3,6)
CREATE TABLE #T2 ([Values] INT) INSERT INTO #T2 VALUES (1),(2),(3),(4)
SELECT * FROM #T1
SELECT * FROM #T2
SELECT A.ID
FROM
( SELECT ID , COUNT(DISTINCT [Values]) AS Count FROM #T1
GROUP BY ID
) A
JOIN
(
SELECT T1.ID, COUNT(DISTINCT T2.[Values]) Count
FROM #T1 T1
JOIN #t2 T2
ON T1.[Values] = T2.[Values]
GROUP BY T1.ID
) B
ON A.ID = B.ID AND A.Count = B.Count