Any way to simplify my code? Left joining multiple select statements - sql

I figured out a way to combine 6 different select statements into one very long row which I can use my select statement to filter data out of. It works just like I need it to, however I feel like I have a ton of redundant code. Is there any way to simplify my code without changing the functionality at all?
SELECT * FROM
(
SELECT row1 FROM db1
JOIN db2 ON ...
JOIN db3 ON ...
WHERE ...) t1
LEFT JOIN
(
SELECT value_to_join FROM db4 v1, db1
JOIN db2 ON ...
JOIN db3 ON ...
WHERE ...) t2
ON t1.other_value = t2.other_value
LEFT JOIN
(
SELECT value_to_join FROM db4 v2, db1
JOIN db2 ON ...
JOIN db3 ON ...
WHERE ...) t3
ON t1.other_value = t3.other_value
My output is a row from the first select statement joined with 5 different values from db4. These 5 values can only be joined with db1 when I join the other tables (db2, db3) because there is no common column to join on.
Some more information: This format of left join is used up to t6, with the ON being t1.value = tn.value with n increasing respectively. The join statements in each subquery are the same in all 6, so I'm assuming there has to be a way to simplify that. The '...' is just a mess of code that comes after each clause.

If your RDBMS supports not-so-old SQL versions, (SQL 3 / SQL:1999), you may use CTE to achieve this:
WITH myquery (value,…) AS (
SELECT * FROM db4, db1
JOIN db2 ON ...
JOIN db3 ON ...
WHERE ...)
SELECT * FROM
(
SELECT * FROM db1
JOIN db2 ON ...
JOIN db3 ON ...
WHERE ...) t1
LEFT JOIN myquery t2
ON t1.value = t2.value
LEFT JOIN myquery t3
ON t1.value = t3.value
…
However, you will need to replace "value,…" and "SELECT *" in the first query by the exact list of wished columns.

Related

Use wildcards that are stored in table columns in SQL-queries with MS Access

I want to join two tables in Access based on different wildcards for different rows.
The first, table1, contains rows with different wildcards and table2 contains the column that should be matched with the wildcards in table1.
I imagine the SQL code to look like:
SELECT *
FROM table2
LEFT JOIN table1
ON table2.subject LIKE table1.wildcard
The tables look like this: https://imgur.com/a/O9OPAL6
The third pictures shows the result that I want.
How do I execute the join or is there an alternative?
I don't think MySQL support non-equality conditions for JOINs. So, you can do this as:
SELECT * -- first get the matches
FROM table2 as t2, -- ugg, why doesn't it support CROSS JOIN
table1 as t1
WHERE t2.subject LIKE t1.wildcard
UNION ALL
SELECT * -- then get the non-matches
FROM table2 as t2 LEFT JOIN
table1 as t1
ON 1 = 0 -- always false but gets the same columns
WHERE NOT EXISTS (SELECT 1
FROM table1 as t1
WHERE t2.subject LIKE t1.wildcard
);

SQL alternative to sub-query in SELECT Item list

I have RDBMS table and Queries which are working perfectly. I have offloaded data from RDBMS to HIVE table.To run the existing queries on HIVE, we need first to make them compatible to HIVE.
Let's take below example with sub-query in select item list. It is syntactically valid and working fine on RDBMS system. But It Will not work on HIVE As per HIVE manual , Hive supports subqueries only in the FROM and WHERE clause.
Example 1 :
SELECT t1.one
,(SELECT t2.two
FROM TEST2 t2
WHERE t1.one=t2.two) t21
,(SELECT t3.three
FROM TEST3 t3
WHERE t1.one=t3.three) t31
FROM TEST1 t1 ;
Example 2:
SELECT a.*
, CASE
WHEN EXISTS
(SELECT 1
FROM tblOrder O
INNER JOIN tblProduct P
ON O.Product_id = P.Product_id
WHERE O.customer_id = C.customer_id
AND P.Product_Type IN (2, 5, 6, 9)
)
THEN 1
ELSE 0
END AS My_Custom_Indicator
FROM tblCustomer C
INNER JOIN tblOtherStuff S
ON C.CustomerID = S.CustomerID ;
Example 3 :
Select component_location_id, component_type_code,
( select clv.LOCATION_VALUE
from stg_dev.component_location_values clv
where identifier_code = 'AXLE'
and component_location_id = cl.component_location_id ) as AXLE,
( select clv.LOCATION_VALUE
from stg_dev.component_location_values clv
where identifier_code = 'SIDE'
and component_location_id = cl.component_location_id ) as SIDE
from stg_dev.component_locations cl ;
I want to know the possible alternative of sub-queries in select item list to make it compatible to hive. Apparently I will be able to transform existing queries in HIVE format.
Any help and guidance is highly appreciated !
The query you provided could be transformed to a simple query with LEFT JOINs.
SELECT
t1.one, t2.two AS t21, t3.three AS t31
FROM
TEST1 t1
LEFT JOIN TEST2 t2
ON t1.one = t2.two
LEFT JOIN TEST3 t3
ON t1.one = t3.three
Since there is no limitation in the subqueries, the joins will return the same data. (The subqueries should return only one or no row for each row in TEST1.)
Please note, that your original query could not handle 1..n connections. In most DBMS, subqueries in the SELECT list should return only with a resultset with one columns and one or no row.
Based on HIVE manual:
SELECT t1.one, t2.two, t3.three
FROM TEST1 t1,TEST2 t2, TEST3 t3
WHERE t1.one=t2.two AND t1.one=t3.three;
SELECT t1.one,t2.two,t3.three FROM TEST1 t1 INNER
JOIN TEST2 t2 ON t1.one=t2.two INNER JOIN TEST3 t3
ON t1.one=t3.three WHERE t1.one=t2.two AND t1.one=t3.three;
SELECT t1.one,t2.two as t21,t3.three as t31 FROM TEST1 t1
INNER JOIN TEST2 t2 ON t1.one=t2.two
INNER JOIN TEST3 t3 ON t1.one=t3.three

Is it possible to use subquery in join condition in Access?

In postgresql I can use subquery in join condition
SELECT *
FROM table1 LEFT JOIN table2
ON table1.id1 = (SELECT id2 FROM table2 LIMIT 1);
But when I try to use it in Access
SELECT *
FROM table1 LEFT JOIN table2
ON table1.id1 = (SELECT TOP 1 id2 FROM table2);
I get syntax error. Is it actually impossible in Access or just my mistake?
I know that I can get the same result with WHERE, but my question is about possibilities of JOIN in Access.
It's not possible, per the MSDN documentation:
Syntax
FROM table1 [ LEFT | RIGHT ] JOIN table2 ON table1.field1 compopr table2.field2
And (emphasis mine):
field1, field2: The names of the fields that are joined. The fields must be of the same data type and contain the same kind of data, but they do not need to have the same name.
It appears you can't even have hard-coded values in your join; you must specify the column name to join against.
In your case, you would want:
SELECT *
FROM Table1
LEFT JOIN (
SELECT DISTINCT TOP 1 ID
FROM Table2
ORDER BY ID
) Table2Derived ON Table1.ID = Table2Derived.ID

SQL - join multiple tables, with one little catch

My apologies in advance if this particular question has already been asked and answered ... there so many different particular ways the JOIN command is used that it can be difficult to find the exact answer to a given problem. I'm a SQL novice, so ... if the solution exists, feel free to point me to it.
I'm trying to join 3 different tables, and I believe what I want is equivalent to a FULL OUTER JOIN (not supported by MySQL, as I understand) on all 3 tables. Consider a Venn diagram with 3 circles; I want the full union of all 3 circles, including the full intersection, all three pair-wise joins (where one table returns NULLs), and all three single instances (where two tables return NULLs). I believe what I've got here will work, but it's brute-force and I'm sure there is a more efficient way. I'm also a bit concerned with my use of WHERE NOT EXISTS, so please correct me if necessary. Here's the gist of my code:
// Intersection of all three tables
SELECT [table1.cols], [table2.cols], [table3.cols]
FROM table1
INNER JOIN table2
ON table1.col1 = table2.col1
INNER JOIN table3
ON table1.col1 = table3.col1
UNION ALL
// Intersection of tables one and two
SELECT [table1.cols], [table2.cols], [NULLS]
FROM table1
INNER JOIN table2
ON table1.col1 = table2.col1
WHERE NOT EXISTS (table1.col1 = table3.col1)
UNION ALL
// Intersection of tables two and three
SELECT [NULLS], [table2.cols], [table3.cols]
FROM table2
INNER JOIN table3
ON table2.col1 = table3.col1
WHERE NOT EXISTS (table2.col1 = table1.col1)
UNION ALL
// Intersection of tables three and one
SELECT [table1.cols], [NULLS], [table3.cols]
FROM table3
INNER JOIN table1
ON table3.col1 = table1.col1
WHERE NOT EXISTS (table3.col1 = table2.col1)
UNION ALL
// Only in table one
SELECT [table1.cols], [NULLS], [NULLS]
FROM table1
WHERE NOT EXISTS ((table1.col1 = table2.col1))
AND NOT EXISTS ((table1.col1 = table3.col1))
UNION ALL
// Only in table two
SELECT [NULLS], [table2.cols], [NULLS]
FROM table2
WHERE NOT EXISTS ((table2.col1 = table1.col1))
AND NOT EXISTS ((table2.col1 = table3.col1))
UNION ALL
// Only in table three
SELECT [NULLS], [NULLS], [table3.cols]
FROM table3
WHERE (NOT EXISTS (table3.col1 = table1.col1))
AND (NOT EXISTS (table3.col1 = table2.col1))
TIA for your help, and your grace. :)
to simulate your full outer join, I would pre-query just the UNIQUE IDs you are EXPECTING, then LEFT JOIN to each other...
select
AllPossibleKeys.CommonID,
T1a.*,
T2a.*,
T3a.*
from
( select distinct T1.col1 as CommonID
from table1 T1
UNION
select distinct T2.col1 as CommonID
from table2 T2
UNION
select distinct T3.col1 as CommonID
from table1 T3 ) as AllPossibleKeys
LEFT JOIN table1 T1a
on AllPossibleKeys.CommonID = T1a.col1
LEFT JOIN table2 T2a
on AllPossibleKeys.CommonID = T2a.col1
LEFT JOIN table3 T3a
on AllPossibleKeys.CommonID = T3a.col1

Left join between 2 tables using 3 columns and joing to a third table on Oracle

i am using Oracle and need to left join 2 tables (which are actually the same table with alias) based on 3 columns and then join with a third table. What should be the best syntax?
Select table_3.column_x
From (table_1 left join table_2
Using (column_1 , column_2 , column_3)), table_3
Where Table_2.column_1 = table_3.column_1
Should I use ‘,’ on the ‘using statement or ‘AND’? Where exactly should I insert the table_3 statement even if it is not used on the left join?
Using ANSI SQL:
select * from
TABLE1 "TABLE1"
left join TABLE1 "TABLE2" on(TABLE1.c1 = TABLE2.C1 and TABLE1.c2 = TABLE2.C2)
left join TABLE3 "TABLE3" on(TABLE1.c3 = TABLE3.c3)
Using Oracle Join Syntax you have:
select * from TABLE1 "TABLE1", TABLE1 "TABLE2", TABLE3 "TABLE3"
where
TABLE1.c1 = TABLE2.c1 (+)
and TABLE1.c2 = TABLE2.c2 (+)
and TABLE1.c3 = TABLE3.c3 (+)
(+) here represents the left join. I personally prefer ANSI SQL way. It seems cleaner to me. Your join predicates might not be the same with my example, keep that in mind.