SQL DB2 store query result into variable - sql

Usind a DB2 tables:
This is what is done manually in a table
select app_id from table_app where APP_NAME='App_Temp';
gets me an ID, say it's 234
I copy than and do:
select * form table_roles where role_app_id=234;
gets me a row , which is my desired end result.
Is there a way save the result of the first one into a variable and do the second query without the manual step in between using local variables?
I know, you can query out the information with a very simple join between two tables, but I'd like to know, how it works with variables. Is there a way?

Just can just plug it in:
select *
from table_roles
where role_app_id = (select app_id from table_app where APP_NAME = 'App_Temp');
If there can be more than one match, use in instead of =.
You can also phrase this as a join:
select r.*
from table_roles r join
table_app
on r.role_app_id = a.app_id and APP_NAME = 'App_Temp';
However, this might return duplicates, if two apps have the same name. In that case, use select distinct:
select distinct r.*
from table_roles r join
table_app
on r.role_app_id = a.app_id and APP_NAME = 'App_Temp';

Related

Give alias to query result

Let's take this piece of code as example:
SELECT *
FROM (SELECT Players.Team, AVG(Players.BirthDate) AS AvgBirthDate
FROM Players
GROUP BY Players.Team)
WHERE AvgBirthDate = (SELECT MAX(AvgBirthDate)
FROM (SELECT Players.Team, AVG(Players.BirthDate) AS AvgBirthDate
FROM Players
GROUP BY Players.Team))
My question is if there is a way to give an alias to the whole query result so that something like this would be possible:
SELECT *
FROM (SELECT Players.Team, AVG(Players.BirthDate) AS AvgBirthDate
FROM Players
GROUP BY Players.Team) AS QueryResult
WHERE AvgBirthDate = (SELECT MAX(AvgBirthDate)
FROM QueryResult)
URL to the code/db
You can use With clause. If it's not possible, you should consider using a view or a temporary table to store the result of a query that might be use several times after its execution.

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 :-)

PyPika how to select star minus a column

I'm trying to use PyPika to build a select statement. Both tables have an id column, and I'm trying to select all columns from both tables except the id column from the first table.
This is the query I want to end up with, which runs properly in BigQuery:
SELECT t.* EXCEPT(id), s.* from t join s on t.id = s.id
I haven't been able to figure out how to get the EXCEPT into the select clause.
I've tried the following syntax, but the except_of() isn't allowed in this context:
t = Table("t")
s = Table("s")
query = Query.from_(t).join(s).on(t.id == s.id).select(t.star.except_of("id")).select(s.star)
I also tried a custom function, but that puts an invalid comma in the resulting query. This is what I tried:
except_select = CustomFunction("EXCEPT", ["column_to_exclude"])
query = Query.from_(t).join(s).on(t.id == s.id).select(t.star).except_select("id")).select(s.star)
which incorrectly generates
SELECT t.*, EXCEPT(id), s.* from t join s on t.id = s.id
Does anyone have any suggestions on how to solve this problem?

I want to join two tables with a common column in Big query?

To join the tables, I am using the following query.
SELECT *
FROM(select user as uservalue1 FROM [projectname.FullData_Edited]) as FullData_Edited
JOIN (select user as uservalue2 FROM [projectname.InstallDate]) as InstallDate
ON FullData_Edited.uservalue1=InstallDate.uservalue2;
The query works but the joined table only has two columns uservalue1 and uservalue2.
I want to keep all the columns present in both the table. Any idea how to achieve that?
#legacySQL
SELECT <list of fields to output>
FROM [projectname:datasetname.FullData_Edited] AS FullData_Edited
JOIN [projectname:datasetname.InstallDate] AS InstallDate
ON FullData_Edited.user = InstallDate.user
or (and preferable)
#standardSQL
SELECT <list of fields to output>
FROM `projectname.datasetname.FullData_Edited` AS FullData_Edited
JOIN `projectname.datasetname.InstallDate` AS InstallDate
ON FullData_Edited.user = InstallDate.user
Note, using SELECT * in such cases lead to Ambiguous column name error, so it is better to put explicit list of columns/fields you need to have in your output
The way around it is in using USING() syntax as in example below.
Assuming that user is the ONLY ambiguous field - it does the trick
#standardSQL
SELECT *
FROM `projectname.datasetname.FullData_Edited` AS FullData_Edited
JOIN `projectname.datasetname.InstallDate` AS InstallDate
USING (user)
For example:
#standardSQL
WITH `projectname.datasetname.FullData_Edited` AS (
SELECT 1 user, 'a' field1
),
`projectname.datasetname.InstallDate` AS (
SELECT 1 user, 'b' field2
)
SELECT *
FROM `projectname.datasetname.FullData_Edited` AS FullData_Edited
JOIN `projectname.datasetname.InstallDate` AS InstallDate
USING (user)
returns
user field1 field2
1 a b
whereas using ON FullData_Edited.user = InstallDate.user gives below error
Error: Duplicate column names in the result are not supported. Found duplicate(s): user
Don't use subqueries if you want all columns:
SELECT *
FROM [projectname.FullData_Edited] as FullData_Edited JOIN
[projectname.InstallDate] as InstallDate
ON FullData_Edited.uservalue1 = InstallDate.uservalue2;
You may have to list out the particular columns you want to avoid duplicate column names.
While you are at it, you should also switch to standard SQL.

Ensuring two columns only contain valid results from same subquery

I have the following table:
id symbol_01 symbol_02
1 abc xyz
2 kjh okd
3 que qid
I need a query that ensures symbol_01 and symbol_02 are both contained in a list of valid symbols. In other words I would needs something like this:
select *
from mytable
where symbol_01 in (
select valid_symbols
from somewhere)
and symbol_02 in (
select valid_symbols
from somewhere)
The above example would work correctly, but the subquery used to determine the list of valid symbols is identical both times and is quite large. It would be very innefficient to run it twice like in the example.
Is there a way to do this without duplicating two identical sub queries?
Another approach:
select *
from mytable t1
where 2 = (select count(distinct symbol)
from valid_symbols vs
where vs.symbol in (t1.symbol_01, t1.symbol_02));
This assumes that the valid symbols are stored in a table valid_symbols that has a column named symbol. The query would also benefit from an index on valid_symbols.symbol
You could try use a CTE like;
WITH ValidSymbols AS (
SELECT DISTINCT valid_symbol
FROM somewhere
)
SELECT mt.*
FROM MyTable mt
INNER JOIN ValidSymbols v1
ON mt.symbol_01 = v1.valid_symbol
INNER JOIN ValidSymbols v2
ON mt.symbol_02 = v2.valid_symbol
From a performance perspective, your query is the right way to do this. I would write it as:
select *
from mytable t
where exists (select 1
from valid_symbols vs
where t.symbol_01 = vs.valid_symbol
) and
exists (select 1
from valid_symbols vs
where t.symbol_02 = vs.valid_symbol
) ;
The important component is that you need an index on valid_symbols(valid_symbol). With this index, the lookup should be pretty fast. Appropriate indexes can even work if valid_symbols is a view, although the effect depends on the complexity of the view.
You seem to have a situation where you have two foreign key relationships. If you explicitly declare these relationships, then the database will enforce that the columns in your table match the valid symbols.