PyPika how to select star minus a column - pypika

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?

Related

TSQL / SQL - Error: Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I'm hoping someone can point me in the right direction here.
DB #1 NAME: "Wayin_Integration_SFMC_AD"
And I'm trying to merge with this Master table (DB #2): "Master_Users_SVOC_test_vt"
Assuming everyone in "Wayin_Integration_SFMC_AD" already has a primary key and record in "Master_Users_SVOC_test_vt", now I want to MERGE INTO the remaining data for that record.
Problem is, most of my fields aren't included in the GROUP BY clause.
Do I need to use a subquery here? I am very new to SQL. Here is the snippet that I am unsure of. Without the GROUP BY this would work, but it's the grouping that is confusing me.
ERROR MESSAGE: "Column 'Wayin_Integration_SFMC_AD.First_Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
"
which is the first field not included in the GROUP BY clause.
THIS IS THE SQL THAT ISN'T WORKING:
MERGE INTO [bo_marketing_capability_dev].[dbo].[Master_Users_SVOC_test_vt] AS m
USING (
SELECT
m.subscriber_key,
m.email_address,
w.[First_Name] AS first_name,
w.[Last_Name] AS last_name,
, MAX (w.DateAdded) AS wayin_DateAdded
FROM Wayin_Integration_SFMC_AD w
INNER JOIN Master_Users_SVOC_test_vt m
ON w.Email = m.email_address
GROUP BY subscriber_key, w.[Email], m.email_address
) AS SRC
ON ([SRC].[email_address] = [m].[email_address])
MERGE INTO [bo_marketing_capability_dev].[dbo].[Master_Users_SVOC_test_vt] AS m
USING (
SELECT
m.subscriber_key,
m.email_address,
w.[First_Name] AS first_name,
w.[Last_Name] AS last_name,
, MAX (w.DateAdded) AS wayin_DateAdded
FROM Wayin_Integration_SFMC_AD w
INNER JOIN Master_Users_SVOC_test_vt m
ON w.Email = m.email_address
GROUP BY m.subscriber_key, m.email_address, w.[First_Name], w.[Last_Name]
) AS SRC
ON ([SRC].[email_address] = [m].[email_address])
Try above code.
GROUP BY should have all non aggregate columns.

how to use listagg operator so that the query should fetch comma separated values

SELECT (SELECT STRING_VALUE
FROM EMP_NODE_PROPERTIES
WHERE NODE_ID=AN.ID ) containedWithin
FROM EMP_NODE AN
WHERE AN.STORE_ID = ALS.ID
AND an.TYPE_QNAME_ID=(SELECT ID
FROM EMP_QNAME
where LOCAL_NAME = 'document')
AND
AND AN.UUID='13456677';
from the above query I am getting below error.
ORA-01427: single-row subquery returns more than one row
so how to change the above query so that it should fetch comma separated values
This query won't return error you mentioned because
there are two ANDs and
there's no ALS table (or its alias).
I suggest you post something that is correctly written, then we can discuss other errors.
Basically, it is either select string_value ... or select id ... (or even both of them) that return more than a single value.
The most obvious "solution" is to use select DISTINCT
another one is to include where rownum = 1
or, use aggregate functions, e.g. select max(string_value) ...
while the most appropriate option would be to join all tables involved and decide which row (value) is correct and adjust query (i.e. its WHERE clause) to make sure that desired value will be returned.
You would seem to want something like this:
SELECT LISTAGG(NP.STRING_VALUE, ',') WITHIN GROUP(ORDER BY NP.STRING_VALUE)
as containedWithin
FROM EMP_NODE N
JOIN EMP_QNAME Q
ON N.TYPE_QNAME_ID = Q.ID
LEFT JOIN EMP_NODE_PROPERTIES NP
ON NP.NODE_ID = N.ID
WHERE Q.LOCAL_NAME = 'document'
AND AN.UUID = '13456677';
This is a bit speculative because your original query would not run for the reason explained by Littlefoot.

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.

Update largest date, matching two fields

tables
Hi, I'm looking to update the last column in a blank table. Picture shows input and desired output. Trying to pick the largest date where workorder and state match.
I've tried a couple different codes:
UPDATE mytable
SET mytable.orderstartdate = MAX(table2.earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
;
"Syntax Error (missing operator) in query expression 'MAX(table2.earliestdate) FROM mytable as table2'."
UPDATE mytable
SET mytable.orderstartdate = (
SELECT max(earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
)
;
"Operation must use an updateable query"
Edit - click tables link for image.
Write PL/SQL Code.
First, select DISTINCT WorkOrder and State and capture in variables.
Now, Iterate the list and Write a query to get max date i.e. max(date) using work_order and State in where clause. Capture the
date.
Now, In the same loop write update query setting max(date) and workorder and State in where clause.
UPDATE table A
SET A.orderstartDate = (SELECT max(earliestdate)
FROM table B
WHERE A.WorkOrder = B.WorkOrder
GROUP BY WorkOrder)
not sure if access supports correlated subqueries but if it does...
and if not...
UPDATE table A
INNER JOIN (SELECT WorkOrder, max(OrderStartDate) MOSD
FROM Table B
GROUP BY WorkOrder) C
ON A.WorkOrder = C.workOrder
SET A.OrderStartDate = C.MOSD
Check database open mode, it may be locked for editing, or you may have no permission to to file.

SQL DB2 store query result into variable

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';