SQL cannot use IN with CTE but works with the same subquery - sql

QUESTION
When I save my table into a CTE, then use it with IN in another query it is considered as error.
WITH id_list AS (
SELECT DISTINCT tracking_id
FROM table_a
)
SELECT col_a, col_b, col_c
FROM table_b
WHERE tracking_id IN (id_list)
But in the same time, if I put the same query as subquery with IN it works correctly.
SELECT col_a, col_b, col_c
FROM table_b
WHERE tracking_id IN (
SELECT DISTINCT tracking_id
FROM table_a
)
I want to know the reason why this situation occur. Why can't we use CTE table directly with IN?
Thanks.

Related

in oracle query, select only few columns with union

I have two tables something like this:
TABLE_1:
COL_A (int), COL_B (float), COL_C (float)
and
TABLE_2:
COL_A (int), COL_B (varchar), COL_C (varchar)
My query is using a UNION to get only COL_A(int) from table 2 like
SELECT COL_A, COL_B, COL_C FROM table1 UNION
SELECT COL_A FROM table2
It's throwing an error. How do we get the results?
All subquery members of a UNION must have the same number and types of columns. In your case the first subquery has three columns, but the second one has only one.
Solution: pad the second subquery with nulls.
For example:
select COL_A, COL_B, COL_C from table1
union
select COL_A, null, null from table2

Can I use column names as data

I have to check the data in each column in 7000 tables.
So I want to insert into Temp_Table has Columns ( Table_name, Column_name, Data)
eg.
SELECT * FROM TABLE_A;
COL_A
COL_B
COL_C
DATA_A1
DATA_B1
DATA_C1
DATA_A2
DATA_B2
DATA_C2
I want to insert into Temp_table
eg.
TABLE_NM
COL_NM
DATA
TABLE_A
COL_A
DATA_A1
TABLE_A
COL_A
DATA_A2
TABLE_A
COL_B
DATA_B1
TABLE_A
COL_B
DATA_B2
TABLE_A
COL_C
DATA_C1
TABLE_A
COL_C
DATA_C2
Is there any way?
you can do this using union all from metadata.
select 'TABLE_A' TABLE_NM, 'COL_A' COL_NM, COL_A DATA from table_a
union all
select 'TABLE_A' TABLE_NM, 'COL_B' COL_NM, COL_B DATA from table_a
union all
select 'TABLE_A' TABLE_NM, 'COL_C' COL_NM, COL_C DATA from table_a
...
Put the list of table and columns in XL and then create a formula to create the whole query. But list of tables and columns - you need to get from metadata.

Create fake indexing column in Teradata SQL

I have the statement:
SELECT col_a, col_b, col_c from database.table sample 50;
I want my output to look like this:
id col_a col_b col_c
1 data goes here
2 data goes here
3 data goes here
4 data goes here
5 data goes here
6 data goes here
Basically - I need to create a column for id that starts at 1 and auto-increments with each row that's retrieved.
How do I do this?
If you actually want the sampled rows numbered:
SELECT ROW_NUMBER() OVER (ORDER BY some_field),
dt.*
FROM
(
SELECT col_a, col_b, col_c
FROM database.table
SAMPLE 50
) AS dt
Instead of SAMPLE you might also use TOP, but then it's not random anymore.
You can use row_number():
select row_number() over (order by ??) as id, col_a, col_b, col_c
from t;
The ?? represents the column/expression the gives the ordering for the id.

SELECT statement on top of UNION statement

select *
from
{
SELECT
ID, CLASS, CHANGE_NUMBER AS OBJECT_NUMBER
FROM table_A
UNION
SELECT
ID, CLASS, CUST_NO AS OBJECT_NUMBER
FROM table_B
ORDER BY ID
} x where x.id ='5434';
Help me to run this query.
I am getting error "invalid table name"
I would suggest writing the query like this:
select x.*
from (SELECT ID, CLASS, CHANGE_NUMBER AS OBJECT_NUMBER FROM table_A
UNION ALL
SELECT ID, CLASS, CUST_NO AS OBJECT_NUMBER FROM table_B
) x
where x.id = '5434';
Notes:
The curly braces are probably your syntax problem.
Use UNION ALL instead of UNION, unless you really want to incur the overhead of removing duplicates.
The ORDER BY is not needed. After all, you are only choosing one id.
If you do have an ORDER BY, it is better practice to put it in the outer query than in the subquery.
Use '(' bracket instead of '{'.
select * from
(
SELECT ID,CLASS, CHANGE_NUMBER AS OBJECT_NUMBER FROM table_A
UNION
SELECT ID,CLASS,CUST_NO AS OBJECT_NUMBER FROM table_B
ORDER BY ID
) x where x.id ='5434';

How to use group by with union in T-SQL

How can I using group by with union in T-SQL? I want to group by the first column of a result of union, I wrote the following SQL but it doesn't work. I just don't know how to reference the specified column (in this case is 1) of the union result.
SELECT *
FROM ( SELECT a.id ,
a.time
FROM dbo.a
UNION
SELECT b.id ,
b.time
FROM dbo.b
)
GROUP BY 1
You need to alias the subquery. Thus, your statement should be:
Select Z.id
From (
Select id, time
From dbo.tablea
Union All
Select id, time
From dbo.tableb
) As Z
Group By Z.id
GROUP BY 1
I've never known GROUP BY to support using ordinals, only ORDER BY. Either way, only MySQL supports GROUP BY's not including all columns without aggregate functions performed on them. Ordinals aren't recommended practice either because if they're based on the order of the SELECT - if that changes, so does your ORDER BY (or GROUP BY if supported).
There's no need to run GROUP BY on the contents when you're using UNION - UNION ensures that duplicates are removed; UNION ALL is faster because it doesn't - and in that case you would need the GROUP BY...
Your query only needs to be:
SELECT a.id,
a.time
FROM dbo.TABLE_A a
UNION
SELECT b.id,
b.time
FROM dbo.TABLE_B b
Identifying the column is easy:
SELECT *
FROM ( SELECT id,
time
FROM dbo.a
UNION
SELECT id,
time
FROM dbo.b
)
GROUP BY id
But it doesn't solve the main problem of this query: what's to be done with the second column values upon grouping by the first? Since (peculiarly!) you're using UNION rather than UNION ALL, you won't have entirely duplicated rows between the two subtables in the union, but you may still very well have several values of time for one value of the id, and you give no hint of what you want to do - min, max, avg, sum, or what?! The SQL engine should give an error because of that (though some such as mysql just pick a random-ish value out of the several, I believe sql-server is better than that).
So, for example, change the first line to SELECT id, MAX(time) or the like!
with UnionTable as
(
SELECT a.id, a.time FROM dbo.a
UNION
SELECT b.id, b.time FROM dbo.b
) SELECT id FROM UnionTable GROUP BY id