Trying to pull tables from a list to insert into a loop - sql

I'm using an Oracle database where I need to run the same query on a multitude of customer database tables all held in the same database.
The query is a select command and runs as such:
select id from customer1_table name where customer1_table.row = 1234
The problem is, instead of running the command 100 times I'm trying to figure out if I can change cusotmer1 to point to a list with all 100 customer names (they each have a unique name for the same table to denote who belongs where) in a loop statement and each successive run of the loop picks a different customer name and inserts it where needed into the select statement. Any help is GREATLY appreciated.

You can use list selection such as:
SELECT * FROM table1 WHERE ID IN (1,2,3,4,...,1001,1002,...)
Syntax may vary between database types.

You could just use a WITH clause in order to define a scope and just join it:
WITH names_list AS
(
SELECT name1 AS name FROM dual UNION ALL
SELECT name1 FROM dual UNION ALL
...
SELECT nameN FROM dual
)
SELECT name.id
FROM customer1_table name
INNER JOIN names_list nl ON name.name = nl.name;

Related

How to select the nth column, and order columns' selection in BigQuery

I have this huge table upon which I apply a lot of processing (using CTEs), and I want to perform a UNION ALL on 2 particular CTEs.
SELECT *
, 0 AS orders
, 0 AS revenue
, 0 AS units
FROM secondary_prep_cte WHERE purchase_event_flag IS FALSE
UNION ALL
SELECT *
FROM results_orders_and_revenues_cte
I get a "Column 1164 in UNION ALL has incompatible types : STRING,DATE at [97:5]
Obviously I don't know the name of the column, and I'd like to debug this but I feel like I'm going to waste a lot of time if I can't pin-point which column is 1164.
I also think this is a problem of the order of columns between the CTEs, so I have 2 questions:
How do I identify the 1164th column
How do I order my columns before performing the UNION ALL
I found this similar question but it is for MSSQL, I am using BigQuery
You can get information from INFORMATION_SCHEMA.COLUMNS but you'll need to create a table or view from the CTE:
CREATE OR REPLACE VIEW `project.dataset.secondary_prep_view` as select * from (select 1 as id, "a" as name, "b" as value)
Then:
SELECT * FROM dataset.INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'secondary_prep_view';

Creating categories SQL

I'm sure there is an easy way to do this, but I'm lost. I've tried Case and IF statements, but still nothing.
I've got two tables both holding descriptive text fields. I need to create a link that says,
IF I.desc='Door' then P.desc IN ('Door', 'Hinge','Wood Frame')
ELSE IF I.desc='Cabinet' then P.desc IN ('Door','Hinge','knob','drawer').
Not exactly what my descriptions are, but it's an example of what I need to link. Unique I.desc has to pull multiple P.desc that overlap into other unique I.desc1.
Any help would be greatly appreciated!
To me, it looks as if you needed the third table which would contain pairs of valid combinations. Something like this (Oracle-ish code; you didn't specify which database you use, but it is a simple matter to populate such a table with some data):
create table pairs (i_desc, p_desc) as
select 'Door' , 'Hinge' from dual union all
select 'Door' , 'Wood Frame' from dual union all
select 'Cabinet', 'Door' from dual union all
select 'Cabinet', 'Hinge' from dual union all
select 'Cabinet', 'Drawer' from dual;
It is easy to maintain it; if new elements appear, you'd just insert a new row, e.g.
insert into pairs (i_desc, p_desc) values ('Cabinet', 'Knob');
Query you'd then use would join these 3 tables as
select ...
from i_table i join pairs r on i.desc = r.i_desc
join p_table p on p.desc = r.p_desc
where ...

Want to concatenate column of the second query to the first query but getting errors such as "query block has incorrect number of result columns"

SELECT
ID, PRIM_EMAIL, SEC_EMAIL, PHONE
FROM
STUDENTS.RECORDS
WHERE
ID IN (SELECT ID FROM STUDENTS.INFO WHERE ROLL_NO = '554')
UNION
SELECT NAME
FROM STUDENTS.INFO
WHERE ROLL_NO = '554';
Here Roll_No is a user inserted data so for now I have hard coded it. Basically with the help of ROLL_NO I sort the STUDENTS_INFO table from where I get the ID and based on that I try to get PRIM_EMAIL, SEC_EMAIL, PHONE from the STUDENTS.RECORDS table while matching the foreign keys of both the tables. In addition to the current result set I also want to have the prov_name column.
Any help is very much appreciated. Thank you!
I suspect that you want to put all this information on the same row, which suggests a join rather than union all:
select
r.ID,
r.PRIM_EMAIL,
r.SEC_EMAIL,
r.PHONE,
r.NAME
from STUDENTS.RECORDS r
inner join STUDENTS.INFO i ON i.ID = r.ID
where I.ROLL_NO = '554';
I think the source of your error query block has incorrect number of result columns is coming from trying to union together a table with 4 columns (id, prim_email, sec_email, phone) with 1 column (name).
From your question, I am gathering that you want a single table of id, prim_email, sec_email, phone from students.records and name from students.info.
I think the following query using CTE's might get you (partially) to your final result. You may want to refactor for optimizing performance.
with s_records as ( select * from students.records ),
s_info as ( select * from students.info ),
joined as (
select
s_records.id,
s_records.prim_email,
s_records.sec_email,
s_records.phone,
s_info.name
from s_records
left join s_info
on s_records.roll_no = s_info.roll_no
where roll_np = '554' )
select * from joined
Overall, I think that a join will be part of your solution rather than a union :-)

The number of columns in the two selected tables or queries of a Union query do not match

I have been facing error in MS Access and error is "The number of columns in the two selected tables or queries of a Union query do not match."
Here is my SQL query:
SELECT sale_head.suppliername AS sale_head_suppliername,
sale_head.invoiceno AS sale_head_invoiceno, sale_head.invoicedate,
sale_details.invoiceno AS sale_details_invoiceno, sale_details.suppliername AS sale_details_suppliername,
sale_details.product_code, sale_details.qty, sale_details.totalkg, sale_details.Rate, sale_details.subtotal FROM sale_head
INNER JOIN sale_details ON sale_head.[invoiceno] = sale_details.[invoiceno]
UNION ALL select 'Total', sum(sale_details.subtotal) from sale_details
WHERE (((sale_head.suppliername)='Ramkrishna Creation'));
Am I missing something ? If yes please do let me know.
When you union two or more queries together each query should have the same columns of data with same data type for example :
SELECT Name,LastName,SUM(Salary) FROM tabel1
UNION
SELECT Text1,Text2,SomeMoney FROM table2
is valid (assuming that Name and Text1,LastName and Text2 and Sum of salary and SomeMoney have the same data type but :
SELECT Name,LastName,SUM(Salary) FROM tabel1
UNION
SELECT Text1,SomeMoney FROM table2
(cloumns count mismatch)or
SELECT Name,LastName,SUM(Salary) FROM tabel1
UNION
SELECT Text1,SomeMoney,Text2 FROM table2
(data type mismatch)are not valid union statements.
UPDATE : My answer is according to SQL Standard Definition of Union Statement which states :
The UNION operator is used to combine the
result-set of two or more SELECT statements.
Notice that each SELECT statement within the UNION must have the same
number of columns. The columns must also have similar data types.
Also, the columns in each SELECT statement must be in the same order.
In a UNION, both datasets must have the same number of columns but they don't need to be the same datatype
All queries in a UNION operation must request the same number of fields; however, the fields do not have to be of the same size or data type.
UNION Operation (Microsoft Access SQL)

Compare Items in the "IN" Clause and the resultset

I'd like to achieve something as follows, I have the following query (As simple as this),
SELECT ENT_ID,TP_ID FROM TC_LOGS WHERE ENT_ID IN (1,2,3,4,5).
Now the table TC_LOGS may not have all the items in the IN clause. So assuming that the table TC_LOGS has only 1,2. I'd like to compare the items in the IN clause i.e. 1,2,3,4,5 with 1,2(the resultset) and get a result as FOUND - 1,2 NOT FOUND - 3,4,5. I've have implemented this by applying an XSL transformation on the resultset in the application code, but I'd like to achieve this in a query, which I feel is more of an elegant solution to this problem. Also, I tried the following query with NVL, just to separate out the FOUND and NOT FOUND items as,
SELECT NVL(ENT_ID,"NOT FOUND") FROM TC_LOGS WHERE ENT_ID IN(1,2,3,4,5)
I was expecting a result as 1,2,NOT FOUND,NOT FOUND,NOT FOUND
But the above query doesn't return any result.. I'd appreciate if someone can guide me in the right path here.. Thanks much in advance.
Assuming that the items in your IN list can (or can come) from another query, you can do something like
WITH src AS (
SELECT level id
FROM dual
CONNECT BY level <= 5)
SELECT nvl(ent_id, 'Not Found' )
FROM src
LEFT OUTER JOIN tc_logs ON (src.id = tc_logs.ent_id)
In my case, the src query is just generating the numbers 1 through 5. You could just as easily fetch that data from a different table, load the numbers into a collection that you query using the TABLE operator, load the numbers into a temporary table that you query, etc. depending on how the IN list data is determined.
NVL isn't going to work because no values (including NULLS) are returned when there is no match with the IN statement.
What you can do is something like this:
SELECT NVL(ENT_ID, "NOT FOUND")
FROM TC_LOGS
RIGHT OUTER JOIN (
SELECT 1 AS 'TempID' UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4 UNION
SELECT 5) AS Sub ON ENT_ID = TempID
The outer join will return NULLS for ENT_ID where there are no matches. Note, I'm not an Oracle person so I can't guarantee that this syntax is perfect.
if you have a table (let's use table src )contains all (1,2,3,4,5) values, you can use full join.
You can use (WITH src AS ( SELECT level id FROM dual CONNECT BY level <= 5) as the src table also)
SELECT
ent_id,tl.tp_id,src.tp_id
FROM
src
FULL JOIN
tc_logs tl
USING (ent_id)
ORDER BY
ent_id
Here is the web site for oracle full join.http://psoug.org/snippet/Oracle-PL-SQL-ANSI-Joins-FULL-JOIN_738.htm