How can I nest multple tables into one while modifying them? - sql

I have multiple tables which I need to merge into one after performing some operations into each one of them.
A first nesting was achieved thanks to a (working) "WITH" statement:
With
T1 as (Select col1, col2, col3,...
from *database*
where *condition*)
Select t2.col1, t2.col2, t2.col3, ...
From(
Select
d.col1, d.col2, d.col3,...
from *d*
where *conditions*
Group by d.col1, d.col2, d.col3,...) t2
Inner join T1
on t1.z = t2.x
Where t2.col1 = *condition*
and *conditions*
Group by t2.col1, t2.col2, t2.col3, ...
The problem arises when I try to expand on this and add more layers to the nest.
I have tried to do the following (changes to the previous code are marked in between "**"):
With
T1 as (Select col1, col2, col3,...
from *database*
where *condition*)**,**
**T2 as (**
Select t2.col1, t2.col2, t2.col3, ...
From(
Select
d.col1, d.col2, d.col3,...
from *d*
where *conditions*
Group by d.col1, d.col2, d.col3,...) t2
Inner join T1
on t1.z = t2.x
Where t2.col1 = *condition*
and *conditions*
Group by t2.col1, t2.col2, t2.col3, ...
**)**
**Select t3.col1 as qw, t3.col2 as qe, t3.col3 as qr,...**
**FROM(**
**Select**
**c.col1,**
**c.col2,**
**c.col3, ...**
**from *c***
**where *conditions) t3***
**Inner join t1**
**on t1.col3 = t3.qr**
**where t3.qe = *condition***
**group by t3.qw, t3.qe, t3.qr,...**
In return, I get the following error:
"t3.qr": invalid identifier"
Does anybody knows what the issue is and how can I fix it? I need to figure out how to nest multiple tables in some way, as, after these ones, more table will have to be added

When we write a query we have to write things in the right order.
firstly CTE `with cte_alias as (select ... from ...)
the SELECT: select column_1, column_2 with possible agregate or window functions: SUM, MAX, ROW_NUMBER() etc. There should only be one SELECT which is not in brackets
FROM tables (sub-queries) CTE's etc with JOIN if needed
WHERE conditions which must be boolean (either true or false)
GROUP BY
ORDER BY
only the select is obligatory in mySQL
SELECT Hello AS "speech"; is a valid mySQL query.

Related

How to join two tables on distinct values of a column?

SELECT table1.*
,address
,job
FROM table1
JOIN table2 ON table2.name = table1.name
The above query returns result for duplicate values of name too. How can I convert the query to get only one value for distinct values of name column?
I am using SQL Server
You can easily accomplish this with row_number window function. See query below:
select t1.id, t1.name, t1.pets, t2.address, t2.job
from (
select *,
row_number() over (partition by [name] order by id) rn
from Table1
) t1
join table2 t2 on t1.name = t2.name
where t1.rn = 1
I would recommend a lateral join -- apply -- for this purpose:
SELECT t1.*, t2.address, t2.job
FROM table2 t2 CROSS APPLY
(SELECT t1.*
FROM table1 t1
WHERE t2.name = t1.name
) t1;
Normally, the subquery would have an ORDER BY to specify the ordering. Otherwise the result is indeterminate.
This is often faster than using window functions for this purpose.

Left Join without duplicate rows 1 to 1 join. Make each row in one table only join to one row in the other table

I'm trying to join table 1 to table 2 to get table 3. (See desired output) However, I can't seem to get it to work since there are so many options since the table only contains one value. A left join doesn't seem to work.
I found this: Left Join without duplicate rows from left table
which seems to match my use case, but Outer Apply is not in PrestoDB.
I essentially want to match each row in T1 with a single one in T2.
If I understand correctly, you can use row_number():
select t1.*, t2.col3
from t1 left join
(select t2.*, row_number() over (partition by col2 order by col3 nulls last) as seqnum
from t2
) t2
on t2.col2 = t1.col2 and t2.seqnum = 1;
If you don't have proper keys you get an m:n-join instead of 1:n. You can calculate a row number for both tables which acts (in combination with col2) as key for the following join:
select t1.col1, t1.col2, t2.col3
from
(
select t1.*,
row_number() over (partition by col2 order by col2) as rn
from t1
) as t
left join
(
select t2.*,
row_number() over (partition by col2 order by col2) as rn
from t2
) as t2
on t1.col2 = t2.col2
and t1.rn = t2.rn;

Using a subquery for IN clause Oracle

I am having some trouble using a subquery for the IN clause of a query.
Hard-coding the IN .. values allows the query to execute quickly, but using a subquery slows everything down. Is there a way to speed this query up?
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
*The values for the IN clause will be a list of strings
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in ('str1', 'str2', 'str3', ...)
...
The above works fine.
EDIT:
I think I was oversimplifying the problem. The query I am trying to execute looks like this:
SELECT col1, col2, col3, ...
FROM table1 t1, table2 t2
WHERE t1.col1 IN (SELECT col FROM table3)
and t1.col2 < 50
and t2.col3 = t1.col3
...
You cant write select * from . If you give select * from, it doesnot understand which column to compare with from table2. Use the column name you need.
SELECT * FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
Use JOIN instead,
and keep an index defined on table1.col1 or table2.col3 or table1.col3 or table3.col :
SELECT col1, col2, col3, ...
FROM table1 t1
INNER JOIN table2 t2 on ( t2.col3 = t1.col3 )
INNER JOIN table3 t3 on ( t1.col1 = t3.col )
WHERE t1.col2 < 50;
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. You should write the query as:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE t1.col1 IN (SELECT col FROM table3) AND
t1.col2 < 50;
I would write this using EXISTS, rather than IN:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE EXISTS (SELECT 1 FROM table3 t3 WHERE t1.col1 = t3.col) AND
t1.col2 < 50;
The filtering is all on table1; however, the columns are being compared with inequalities. I would try the following indexes: table2(col3), table1(col2, col1), and table3(col).

ORACLE - Select ROWNUM with distinct multiple COLUMNS

Hi I am invoking SQL quires from java application, Since table has huge data its taking time to process from java side. Now i am invoking 1000 by 1000 records
SELECT t1.col1,t1.col2,t2.col1,t2.col2 FROM(SELECT rownum AS rn,
t1.col1,
t1.col2,
t2.col1,
t2.col2 FROM table1 t1,
table2 t2 WHERE t1.id=t2.id) WHERE rn BETWEEN ? AND ?;
But i have one more query which has distinct values like below
SELECT t1.col1,t1.col2,t2.col1,t2.col2 FROM(SELECT rownum AS rn,
distinct t1.col1,
t1.col2,
t2.col1,
t2.col2 FROM table1 t1,
table2 t2 WHERE t1.id=t2.id) WHERE rn BETWEEN ? AND ?;
But this query is giving error, Not allowing to add rownum AS rn for distinct. Please could you help us to resolve above use case?
In an oracle database the DISTINCT key word is only allowed directly behind the SELECT key word or inside the COUNT function.
Furthermore your SQL will lead to inconsistent results since in an oracle database the order of records is not guaranteed without explicit ORDER BY clause.
you also cannot access the tabla aliases from an inner select so you have to apply column aliases if the columns in the different tables have the same column name.
The best solution would be to to add another layer of nested selects:
SELECT t1_col1, t1_col2, t2_col1, t2_col2
FROM (
SELECT rownum AS rn, inner_tab.*
FROM (
SELECT distinct t1.col1 AS t1_col1,
t1.col2 AS t1_col2,
t2.col1 AS t2_col1,
t2.col2 AS t2_col2
FROM table1 t1,
table2 t2
WHERE t1.id=t2.id
ORDER BY 1 -- you have to decide!
) inner_tab
) WHERE rn BETWEEN ? AND ?;

How to use WITH CLAUSE ...INSERT query in SAP HANA?

Here I used With AS Clause.if i use SELECT query it is working fine but if i use insert query . it gives syntax error.
Can we use WITH ....INSERT in SAP HANA?
Code:
WITH t1 as
(
Select
col1,
col2,
col3
from table1),
t2 as
(
select
a.col4,
a.col5,
a.col1,
b.col3
from table2 a
left outer join t1
on a.col1 = b. col1)
insert into table3
select
c.col4,
c.col5,
c.col3
from t2;
In addition to Serban's correct answer, a general workaround for lack of CTE functionality is to create views instead.
In your case that could be:
create view t1 as
(select
col1,
col2,
col3
from
table1);
create view t2 as
(select
a.col4,
a.col5,
a.col1,
b.col3
from
table2 a
left outer join t1
on a.col1 = b. col1);
insert into table3
select
c.col4,
c.col5,
c.col3
from t2;
Based on my knowledge on HANA, CTEs (~ WITH-based queries) are currently not supported in INSERT clauses. This means that you should directly use sub-queries instead where possible.
IMO, the only scenario that is impossible to create without CTEs are recursive queries (which are not at all supported in HANA). As your query is not recursive, you can re-write and simplify it as follows:
INSERT INTO TABLE3
SELECT T2.COL4, T2.COL5, T1.COL3
FROM TABLE1 AS T1
LEFT OUTER JOIN TABLE2 AS T2
ON T1.COL1 = T2.COL1