I'm trying to solve a problem that requires me to get rows from a table based on the values of other rows from the same table (which I also need in the output).
I'm looking to do the equivalent of the below:
SELECT a.id,a.col1,a.col2 FROM tbl a WHERE col1 = #col
UNION
SELECT b.id,b.col1,b.col2 FROM tbl b WHERE b.col2 IN (SELECT a.col1)
UNION
SELECT c.id,c.col1,c.col2 FROM tbl c WHERE c.col1 IN (SELECT b.col1)
or
(SELECT id,col1,col2 FROM tbl WHERE col1 = #val) a
UNION
SELECT id,col1,col2 FROM tbl b WHERE b.col2 IN (SELECT col1 FROM a)
UNION
SELECT id,col1,col2 FROM tbl c WHERE c.col1 IN (SELECT col1 FROM b)
But both of these are not allowed. Is there some way to achieve this that avoid tediously recursive statements when extended, like the functional statement below:
SELECT * FROM #tbl WHERE col1 = #val
UNION
SELECT * FROM #tbl WHERE col2 = (SELECT col1 FROM #tbl WHERE col1 = #val)
UNION
SELECT * FROM #tbl WHERE col1 = (SELECT col1 FROM #tbl WHERE col2 = (SELECT col1 FROM #tbl WHERE col1 = #val))
fiddle
Is this what you want?
with cte as (
SELECT a.id, a.col1, a.col2
FROM tbl a
WHERE col1 = #col
UNION ALL
SELECT b.id, b.col1, b.col2
FROM tbl b JOIN
cte
ON b.col2 = cte.col1
)
select *
from cte;
You might want select distinct in the outer query or union in the inner one.
The query itself might be more complicated if your relationships have cycles.
Related
I have been working on trying to convert the following SQL-Server code to achieve a similar result in MS Access.
WITH TableA(Col1, Col2, Col3)
AS (SELECT 'Dog',1,1 UNION ALL
SELECT 'Cat',27,86 UNION ALL
SELECT 'Cat',128,92),
TableB(Col1, Col2, Col3)
AS (SELECT 'Dog',1,1 UNION ALL
SELECT 'Cat',27,105 UNION ALL
SELECT 'Lizard',83,NULL)
SELECT CA.*
FROM TableA A
FULL OUTER JOIN TableB B
ON A.Col1 = B.Col1
AND A.Col2 = B.Col2
/*Unpivot the joined rows*/
CROSS APPLY (SELECT 'TableA' AS what, A.* UNION ALL
SELECT 'TableB' AS what, B.*) AS CA
/*Exclude identical rows*/
WHERE EXISTS (SELECT A.*
EXCEPT
SELECT B.*)
/*Discard NULL extended row*/
AND CA.Col1 IS NOT NULL
ORDER BY CA.Col1, CA.Col2
Gives
what Col1 Col2 Col3
------ ------ ----------- -----------
TableA Cat 27 86
TableB Cat 27 105
TableA Cat 128 92
TableB Lizard 83 NULL
So far I have been able to convert get replication of the FULL OUTER JOIN using the following code, but I have been unable to replicate unpivoting the joint rows (CROSS APPLY).
(SELECT *
FROM TableA AA
INNER JOIN TableB BB ON AA.Col1 = BB.Col1
UNION ALL
SELECT *
FROM TableA AA
LEFT JOIN TableB BB ON AA.Col1 = BB.Col1
WHERE BB.[IP Number] IS NULL
UNION ALL
SELECT *
FROM TableA AA
RIGHT JOIN TableB BB ON AA.Col1 = BB.Col1
WHERE AA.Col1 IS NULL
)
I could use some help achieving the same result in a MS-Access query.
From what I can gather, you have two tables that have unique rows. You want to return rows that are present in one table but not the other.
I would suggest aggregation and HAVING for this -- in either database:
SELECT col1, col2, col3
FROM ((SELECT col1, col2, col3 FROM TableA) UNION ALL
(SELECT col1, col2, col3 FROM TableB)
) as ab
GROUP BY col1, col2, col3
HAVING COUNT(*) = 1;
Or alternatively, two NOT EXISTS clauses:
SELECT a.*
FROM TableA as a
WHERE NOT EXISTS (SELECT 1
FROM TableB as b
WHERE (a.col1 = b.col1 OR a.col1 IS NULL AND b.col1 IS NULL) AND
(a.col2 = b.col2 OR a.col2 IS NULL AND b.col2 IS NULL) AND
(a.col3 = b.col3 OR a.col3 IS NULL AND b.col3 IS NULL)
)
UNION ALL
SELECT b.*
FROM TableB as b
WHERE NOT EXISTS (SELECT 1
FROM TableA as a
WHERE (a.col1 = b.col1 OR a.col1 IS NULL AND b.col1 IS NULL) AND
(a.col2 = b.col2 OR a.col2 IS NULL AND b.col2 IS NULL) AND
(a.col3 = b.col3 OR a.col3 IS NULL AND b.col3 IS NULL)
);
Here is a db<>fiddle that uses SQL Server, but the syntax should be basically the same in MS Access.
I am trying to accomplish the following, and I am not sure if it is possible. I have a SELECT Statement that contains an inner SELECT for two of the table columns like so:
SELECT
col1,
col2,
(SELECT SUM(col1)
FROM table2)
AS FirstResultToAdd,
(SELECT SUM(col2)
FROM table3)
AS SecondResultToAdd,
FROM Table1
So my question is: Is it possible to perform a calculation, such as doing a SUM of "FirstResultToAdd" and "SecondResultToAdd, and returning that as a single column result on "Table1"? Also to keep in mind, I have excluded any joins of the tables to keep the example simple.
I believe you want to perform some logic on the result of Sub-query
To add the two sub-query result
SELECT col1,
col2,
(SELECT col1
FROM table2)
AS FirstResultToAdd,
(SELECT col2
FROM table3)
AS SecondResultToAdd,
(SELECT col1
FROM table2)
+
(SELECT col2
FROM table3)
AS total
FROM table1
To make the query more readable you can make the original query as Sub-Select and perform the logic in Outer query
just nest one more time...
select col1, col2, sum( FirstResultToAdd )
from (
SELECT
col1,
col2,
(SELECT col1
FROM table2)
AS FirstResultToAdd,
(SELECT col2
FROM table3)
AS SecondResultToAdd,
FROM Table1
)
Edit: Fixed Group By
Try this:
Select A.Col1,
A.Col2,
(B.Col3 + C.Col4)
From(
(Select Col1,
Col2
From [Table1]) A
Inner join (Select Sum(Col3) AS Col3
From [Table2]) B on 1 = 1
Inner join (Select Sum(Col4) AS Col4
From [Table3]) C on 1 = 1
)
Group By A.Col1,
A.Col2,
B.Col3,
C.Col4
I need to select distinct "col1" in table 1 and update "col1" and its class "col1Class" in table2
this is the code i wrote but its not working:
UPDATE testing
SET col1 = a.col , Class = a.Class
from testing inner join
( select distinct col1 , col1Class As col,class
from TestAll
)a
UPDATE B
SET B.CLASS=A.CLASS
FROM TESTING B
JOIN (SELECT DISTINCT COL1 AS COL,COL1CLASS AS CLASS FROM TESTALL)A
ON B.COL1=A.COL
UPDATE testing
SET col1 = A.col , Class = A.Class
FROM testing INNER JOIN
(SELECT DISTINCT col1 , col1Class As col,class
from TestAll)
as A
ON testing.col1 = A.col AND testing.col1class = A.class
;with cte(col1, colclass)
as
(
select col1, colclass
from table1
group by col1,colclass
)
update t2
set col1 = c.col1, class = c.colClass
from table2 t2
inner join cte c on t2.col1 = c.col1
try this.
I have 4 Select statements for 4 different tables
each Select query gives latest record meeting specified condition
for ex:
Select TOP 1 * from table where column_name = 'something' order by col1 DESC;
Now I have to combine result set of all 4 queries and create a view from combined result set.
create view some_view as
(
(select TOP 1 * from table1 where ....)
UNION ALL
(select TOP 1 * from table2 where ....)
UNION ALL
(select TOP 1 * from table3 where ....)
UNION ALL
(select TOP 1 * from table4 where ....)
)
Some DB's don't let you provide an "order by" clause inside on of the unioned queries.
If you're ordering by col1 desc, it's possible that it's some type of column you can apply min() or max() to.
If that is the case, below could solve your issue (if there aren't too many records, or, if the tables are massive, "col1" and "some_column" are indexed.)
create view some_view as
(
select * from table1
where some_column = 'something'
and col1 = (select max(col1) from table1 where some_column = 'something')
UNION ALL
select * from table2
where some_column = 'something'
and col1 = (select max(col1) from table2 where some_column = 'something')
UNION ALL
select * from table3
where some_column = 'something'
and col1 = (select max(col1) from table3 where some_column = 'something')
UNION ALL
select * from table4
where some_column = 'something'
and col1 = (select max(col1) from table4 where some_column = 'something')
)
I want to insert only Distinct Records from Table "A" to Table "B". Assume both the tables has same structure.
If by DISTINCT you mean unique records that are on TableB that aren't already in TableA, then do the following:
INSERT INTO TableB(Col1, Col2, Col3, ... , Coln)
SELECT DISTINCT A.Col1, A.Col2, A.Col3, ... , A.Coln
FROM TableA A
LEFT JOIN TableB B
ON A.KeyOfTableA = B.KeyOfTableB
WHERE B.KeyOfTableB IS NULL
INSERT INTO B SELECT DISTINCT * FROM A
You might not want the id column of the table to be part of the distinct check, so use this solution if that's the case: https://stackoverflow.com/a/5171345/453673
INSERT INTO TableB
(Col1, Col2, ...)
SELECT DISTINCT Col1, Col2, ...
FROM TableA
INSERT INTO TableB
SELECT *
FROM TableA AS A
WHERE NOT EXISTS(SELECT * FROM TableB AS B WHERE B.Field1 = A.Field1)
-- If need: B.Field2 = A.Field2 and B.Field3 = A.Field3