I have seen several examples to write CE functions. BUt, I have not come across any example where a join is performed on columns with different name.
For example:
With SQL:
select T1.col1, T1.col2, T1.col3 , T2.col4, T2.col5, T2.col6
from table1 T1
inner join table2 T2
on T1.col3 = T2.col7
WITH CE functions:
table1 = CE_COLUMN_TABLE("SCHEMA"."TABLE1",["col1","col2","col3"]);
table2 = CE_COLUMN_TABLE("SCHEMA"."TABLE2",["col4","col5","col6","col7"]);
var_out = CE_JOIN(:table1,:table2,[??],[])
Can anyone please help me in completing the join statement.
Thanks
Mesh
The trick here to use a projection node. A projection will allow you to rename columns and also filter data. You could do something like:
prj_1 = CE_PROJECTION(:emp_table,["ID","FNAME", "LNAME", "AGE", "PAY" AS "SALARY"], '"PAY"' > 1000);
prj_2 = CE_PROJECTION(:address,["EMP_ID" AS "ID", "ADDR1", "ADDR2", "ZIP"]);
join_1 = CE_JOIN(:prj_1, :prj_2, ["ID"]);
Related
The task I am trying to solve is to get all tables out of a long SQL query and its respective columns.
E.g.
SELECT
t1.id, t1.gender, t1.name,
t2.age, t2.salary
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id
Wanted output:
{'table1': ['id', 'gender', 'name'], 'table2': ['age', 'salary']}
I considered using string splitting etc. getting all table names and based on the alias (if available) get the columns.
But this is getting way to complicated if there are multiple joins and maybe also UNIONs.
Is there an available library or smart way to do that?
If it's only for 1 query I would advise to use MS Excel and filter on the table alias. Generate the select statement via MS Excel and you could create something like this:
SELECT
'table1:', t1.id, t1.gender, t1.name,
'table2:',t2.age, t2.salary
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id
In case if this helps.
Take the column name from All_TAB_COLUMN and Pivot it. Still this is not exact result you want.
select * from (
select TABLE_NAME,COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME in
('Table1','Table2'))
pivot
(
max(table_name)
for COLUMN_NAME in ('gender','name','age','salary')
)
order by 1;
I'm trying to write a query that looks something like below.
select t1.t1c1, t1.t1c2, t2.t2c3, t2.t2c4
from table1 t1
left outer join (select top 1 t2c1, t2c2, t2c3, t2c4 from table2
where t2c5 in (select t3c1 from table3 t3
where **t3c2 = t1.t1c2 and t3c3 = t1.t1c3**) t2
on t1.t1c1 = t2.t2c1 and t1.t1c2 = t2.t2c2
What SQL Server does not allow is the highlighted text above - i.e. referencing the table1's columns in the table3 sub query.
Is there a way to achieve this?
I understand that this might not be the most optimal way, is there any other way to achieve this?
You seem to exactly want outer apply. I think it would look like this:
select t1.t1c1, t1.t1c2, t2.t2c3, t2.t2c4
from table1 t1 outer apply
(select top 1 t2c1, t2c2, t2c3, t2c4
from table2
where t2c5 in (select t3c1
from table3 t3
where t3c2 = t1.t1c2 and t3c3 = t1.t1c3
) and
t1.t1c1 = t2.t2c1 and t1.t1c2 = t2.t2c2
) t2;
APPLY is a lot like using a correlated subquery, except it goes in the FROM clause and can return multiple columns and multiple rows.
Note: You should be using ORDER BY when you use TOP.
Guess there are similar questions and the answere might is easy but I cant help my self and thats why I ask you guys.
I have some Data in a DB (Centura/Gupta SQLBase 7)
no Left/Right Join possible - obviously not implemented in sqlbase sql
Here is my select
SELECT
I.IARTNR,
L.ARTNAME
FROM
INVENTUR I,
LAGER L
WHERE
L.ARTSTR = I.IARTNR
AND
I.AB = '2015-81';
returns 20 rows, not 18 as expacted.
INVENTUR rows with AB set to 2015-81 are 18 and in LAGER there are <3000 rows. What I'm trying to do is select all articles von INVENTUR and add the article name thats written in LAGER.
Whats wrong with my select ? Running this "mysterious" since 3 days.
ANSI join syntax for Outer / Inner joins was added in v8.5 onwards ( now upto v12.1 ).
Before v8.5 , you can use the native Gupta Outer / Inner join syntax e.g.
SELECT t1.col1,t2.col1,t1.col2,t2.col2
FROM t1,t2
WHERE t1.col1 = t2.col1(+)
AND t1.col2 = t2.col2(+)
The next example lists customer names and their order numbers,including customers who have made no orders:
SELECT CUSTOMER.CUSTNO,NAME
FROM CUSTOMER,ORDERS
WHERE CUSTOMER.CUSTNO = ORDERS.CUSTNO(*)
The same query using ANSI syntax in SQLBase v8.5 onmwards is:
SELECT CUSTOMER.CUSTNO,NAME
FROM CUSTOMER LEFT OUTER JOIN ORDERS ON CUSTOMER.CUSTNO = ORDERS.CUSTNO
Use explicit joins.
SELECT I.IARTNR, L.ARTNAME
FROM INVENTUR I
INNER JOIN LAGER L ON I.IARTNR = L.ARTSTR
WHERE I.AB = '2015-81';
And if needs be DISTINCT.
SELECT DISTINCT I.IARTNR, L.ARTNAME
FROM INVENTUR I
INNER JOIN LAGER L ON I.IARTNR = L.ARTSTR
WHERE I.AB = '2015-81';
Of course SQLBase has inner / outer joins !
Either Native syntax ( using (+) ) or ANSI .
Here's the syntax:
NATIVE:
SELECT t1.col1, t2.col1, t1.col2, t2.col2
FROM t1, t2
WHERE t1.col1 = t2.col1 (+) AND t1.col2 = t2.col2 (+);
ANSI:
SELECT t1.col1, t2.col1, t1.col2, t2.col2
FROM t2 RIGHT OUTER JOIN t1
ON t1.col1 = t2.col1
AND t1.col2 = t2.col2 ;
p.s. SQLBase is no 'weird' database . v12 recently released will outstrip SQLServer every time in terms of performance , footprint and overall cost of ownership. Please be more aware of your facts before broadcasting nonsense.
I have a somewhat large query (~8 tables being joined, 100 lines of sql or so) that I use frequently in order to join many different data sources together. I would like to be able to pass a parameter into the query so that myself and other members of my team can work off the same code base and just change the time period that we are looking at.
Example code (obviously my actual code is more involved than this, but these are some of the things that I need to do):
SELECT t1.* , x.col1, x.SUM_col3
FROM table1 t1
LEFT JOIN
(
SELECT t2.col1, t3.col2, SUM(t3.col3) as SUM_col3
FROM table2 t2
INNER JOIN table3 t3
ON t2.PI = t3.SI
WHERE t3.col2 NOT LIKE :parameter1
GROUP BY 1,2
QUALIFY ROW_NUMBER() OVER(PARTITION BY t2.col1 ORDER BY t3.col1) = 1
) x
ON t1.col1 = x.col1
WHERE t1.START_DATE >= :parameter2
Solutions I have considered:
Using the '?' prefix in order to enter the parameters at run time. I find this method to be quite inefficient as the entered parameter is retained in the code after running the code.
Using Dynamic SQL to create a procedure which can then be called. I'm struggling to get this method to work as its intended purpose seems to be relatively short queries.
How can I best structure my query and code in order to be able to run something like CALL MY_QUERY(:parameter1,:parameter2) in such a way that it either creates the resulting table in memory (less preferred) or returns a result set that I can then store or use myself (more preferred).
What you are wanting is a Macro in Teradata. A Macro is pretty much just a parameterized view, which is exactly what you are talking about here.
CREATE MACRO myMacro (parameter1 VARCHAR(20), parameter2 DATE)
AS
(
SELECT t1.*
FROM table1 t1
LEFT JOIN
(
SELECT t2.col1, t3.col2, SUM(t3.col3)
FROM table2 t2
INNER JOIN table3 t3
WHERE t3.col2 NOT LIKE :parameter1
GROUP BY 1,2
QUALIFY ROW_NUMBER() OVER(PARTITION BY t2.col1 ORDER BY t3.col1) = 1
) x
ON t1.col1 = x.col1
WHERE t1.START_DATE >= :parameter2;
);
To call it:
Execute myMacro('Harold', DATE '2015-01-01');
I have 2 tables as below:
tblTransaction
tblMobileRegistration
I want to join these 2 tables and count the numbers of raws that specific columns value in that is not '1' as below:
SELECT COUNT(Transaction_MobileErrorCode) FROM T1 WHERE Transaction_MobileErrorCode <> ''
Its my whole query:
SELECT
T1.*,
T2.*,
(SELECT COUNT(Transaction_MobileErrorCode) FROM T1 WHERE Transaction_MobileErrorCode <> '')
FROM
(SELECT MobileRegistration_DateTime, Transaction_MobileErrorCode FROM tblTransaction, tblMobileRegistration
WHERE T1.ID1 = T2.ID1 AND
T1.ID2 = '111111' AND
T1.ID3 = '222222' AND
T1.ID4 = '333333' AND
T1.ID5 = '444444') AS T1,
tblMobileRegistration AS T2
but I got this error:
Invalid object name 'T1'.
so how can I fix it?
thanks for any helping...
It is a bit hard to tell what results you actually want. But this following may do what you want:
SELECT MobileRegistration_DateTime, Transaction_MobileErrorCode,
SUM(CASE WHENTransaction_MobileErrorCode <> '' THEN 1 ELSE 0 END) OVER ()
FROM tblTransaction t JOIN
tblMobileRegistration mr
ON t.ID1 = mr.ID1
WHERE T1.ID2 = '111111' AND
T1.ID3 = '222222' AND
T1.ID4 = '333333' AND
T1.ID5 = '444444';
You should learn to use proper, explicit join syntax. You simply have too many table references for what you probably want to do.
This version uses a window function. You don't specify the database, but this is ANSI standard syntax supported by most databases.
This is your inner most query. Nothing is aliased as T1 (or T2). You are either mixing up your parenthesis, or missing aliases. If you're missing aliases, you really need to get a bit more creative than just using t1 and t2 everywhere. Makes debugging your query very difficult.
SELECT MobileRegistration_DateTime,
Transaction_MobileErrorCode
FROM tblTransaction,
tblMobileRegistration
WHERE T1.ID1 = T2.ID1 AND
T1.ID2 = '111111' AND
T1.ID3 = '222222' AND
T1.ID4 = '333333' AND
T1.ID5 = '444444'
As other folks have said, your query is very confusing. If you really are intending to have all those derived tables, break it down and build it from the inside out.
It was a runtime error.
At first it will checks all columns in select statement from tables but not the assigned table(T1 will created while executing and deleted after that execution)
remove that select statement (from t1) then execute it will work.
(SELECT COUNT(Transaction_MobileErrorCode) FROM T1)
from this line you are getting error