ORA-00918: Column ambiguously defined (Oracle) - sql

I need to select a column as ' ' (empty).
Here is my query:
SELECT NAME, ' ', ' '
FROM TABLE_NAME
GROUP BY NAME
While executing at the database level query there is no problem, but at the code level I am getting Column ambiguously defined Error.
Note From suggestions, that error is because of ' '. So, I wanted to follow
SELECT NAME, ' ' AS EMPTY1, ' ' AS EMPTY2
FROM TABLE_NAME
GROUP BY NAME
How long it's correct or any alternatives, please?

Your solution is correct.
alternative:
SELECT distinct NAME,
' ' AS EMPTY1,
' ' AS EMPTY2
FROM TABLE_NAME

Related

How to pivot in bigQuery using PIVOT?

I am trying to pull rows as columns in bigquery.
This is how my data looks like now:
This is how I want my data to look like:
PS: While I have shown only 3 values in column SUB_CLASS_DESC actual count is in 100s. Hence, I am looking to use Procedural language as per documentation here. I followed the example shared here in towardsdatascience.com and wrote below code, but unfortunately that doesn't work:
DECLARE DEPT_CLASS_SUB_CLASS STRING;
SET DEPT_CLASS_SUB_CLASS = (SELECT CONCAT('("', STRING_AGG(DISTINCT DEPT_CLASS_SUB_CLASS, '", "'), '")')
FROM `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_11_TEST`
);
EXECUTE IMMEDIATE FORMAT("""
CREATE OR REPLACE TABLE `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_PIVOTED_12_TEST` AS
SELECT * FROM
(SELECT HH_ID,DEPT_CLASS_SUB_CLASS,SALE_AMT
FROM `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_11_TEST`
)
PIVOT
(SUM(SALE_AMT)
,FOR DEPT_CLASS_SUB_CLASS IN %s
)""",DEPT_CLASS_SUB_CLASS);
Error I am getting:
Error message suggests to declare before the execute block, and I am doing exactly that, but I don't understand why the error still persists.
I tried declaring variables DEPT_CLASS_SUB_CLASS in different ways but not successful yet. Could anyone please point out where I might be making the mistake.
Much appreciated!
Consider below approach
execute immediate (select '''
select *
from your_table
pivot (any_value(sale_amt) for replace(sub_class_desc, ' ', '_') in (''' || list || '''))
'''
from (
select string_agg(distinct "'" || replace(sub_class_desc, ' ', '_') || "'") list
from your_table
)
)
if applied to dummy data as in your question - output is
How can I save these results into a new pivoted table? Specifically where can I put my CREATE OR REPLACE TABLE?
execute immediate (select '''
create or replace table `your_project.your_dataset.pivot_table` as
select *
from your_table
pivot (any_value(sale_amt) for replace(sub_class_desc, ' ', '_') in (''' || list || '''))
'''
from (
select string_agg(distinct "'" || replace(sub_class_desc, ' ', '_') || "'") list
from your_table
)
);
DEPT_CLASS_SUB_CLASS variable should be placed before any other statement, not just before an execute block being referenced.
From your error message, you seems to declare a variable at [411:1] which means at 411 line. Kindly move it to the top of your script at line 1 and test it again.
you have kind of a PIVOTing problem. I wrote down some test query which do PIVOTing and list columns in an alphabetical order at the same time.
DECLARE sample_data ARRAY<STRUCT<HH_ID STRING, SUB_CLASS_DESC STRING, SALE_AMT FLOAT64>> DEFAULT [
('HHH_001', 'K&B FIXTURE/PLUMBING', 139.),
('HHH_001', 'PULLDOWN KITCHEN FAUCETS', 129.),
('HHH_001', 'TUBULAR REPAIR & REPLACE', 0.)
];
CREATE TEMP TABLE data AS
SELECT r.* REPLACE(TRANSLATE(SUB_CLASS_DESC, ' &/', '___') AS SUB_CLASS_DESC)
FROM UNNEST(sample_data) r
;
EXECUTE IMMEDIATE FORMAT ("""
SELECT *
FROM data
PIVOT (SUM(SALE_AMT) AS sale_amt FOR SUB_CLASS_DESC IN ('%s'));
""", (SELECT STRING_AGG(DISTINCT SUB_CLASS_DESC, "','" ORDER BY SUB_CLASS_DESC ASC) FROM data)
);
Query Result

PL/SQL check to see if an inputted value exists in a different table

Goal:
Verify storeName exists in the storeLocation table & Verify invoiceNumber does not exist In the invoiceHistory table.
With the code I have bellow, I can add to the table using insert into, but when I use a where exists and not exists, I get the following errors:
ORA-06550: line 7, column 5:
PL/SQL: ORA-00933: SQL command not properly ended
ACCEPT storename PROMPT 'Enter StoreName: '
ACCEPT price PROMPT 'Enter Price: '
ACCEPT tax PROMPT 'Enter Tax : '
ACCEPT total PROMPT 'Enter the total: '
ACCEPT invoicenumber PROMPT 'Enter invoice number: '
BEGIN
INSERT INTO order VALUES (
'&storename ',
'&price ',
'&tax',
'&total ',
'&invoicenumber ')
WHERE
EXISTS(
SELECT * FROM storelocation
where upper(storelocation.storename) = upper('&storename '))
AND NOT EXISTS(
SELECT * FROM invoiceHistory
where invoiceHistory.invoicenumber = '&invoicenumber ')
);
COMMIT;
END;
Why is this error occurring and how do I avoid it?
INSERT ... VALUES ... cannot have a WHERE clause. But INSERT ... SELECT ... can.
INSERT INTO order
SELECT '&storename ',
'&price ',
'&tax',
'&total ',
'&invoicenumber '
FROM dual
WHERE EXISTS (SELECT *
FROM storelocation
WHERE upper(storelocation.storename) = upper('&storename '))
AND NOT EXISTS (SELECT *
FROM invoicehistory
WHERE invoicehistory.invoicenumber = '&invoicenumber ');
But you should make a habit of explicitly listing the targeted columns in an INSERT. That makes sure everything goes where it's supposed to go.
(You may also check if you really want/need that trailing space in the string literals.)

Can I Union all tables (700+) and add new column with table name?

I'm using this to help me generate code to union all 700 tables in my database. It works well
select 'select PartNumber, Quantity FROM '+TABLE_NAME +' union all'
FROM INFORMATION_SCHEMA.TABLES
However, I want to add a 3rd column that adds in the table name beside the relevant rows. Is there a way to this using the TABLE_NAME. I.e. so I don't have to manually add the table name for each one.
Just add the tablename in as a column:
select 'select PartNumber, Quantity, '''+TABLE_NAME +''' as table_name from ' + TABLE_NAME + ' union all'
from INFORMATION_SCHEMA.TABLES;
If your tables can have strange characters, you might need to take that into account. Unfortunately, QUOTENAME() doesn't quite do what you need. But replace(table_name, '''', '''''') will replace single quotes with double quotes.

Update single column found in multiple tables

I have the same column in multiple tables in my database. I need to update every table that contains that column where the value is equal to 'xxxx'. There's a very similar stack question here which is close to what I'm looking for - I just need to add another condition in my WHERE statement. I'm not sure how to include it in the query as I keep getting syntax errors.
SELECT 'UPDATE ' + TABLE_NAME + ' SET customer= ''NewCustomerValue'' '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'customer'
The part I'm having problems with is how to include the below line in the 'WHERE' statement.
AND customer='xxxx'
Try like this
SELECT 'UPDATE ' + TABLE_NAME + ' SET customer= ''NewCustomerValue'' where customer=''xxxx'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'customer'
try this:
' AND customer=''xxxx'' ' --(two ' inside a string = ')

How to join attributes in sql select statement?

I want to join few attributes in select statement as one for example
select id, (name + ' ' + surname + ' ' + age) as info from users
this doesn't work, how to do it?
I'm using postgreSQL.
Postgres uses || to concatenate strings; your query needs to be:
select id, (name || ' ' || surname || ' ' || age) as info from users
It should be the key just above the Enter key on a full keyboard, but on mine it's not a sold line - there's a break in the middle of it. You have to hold the Shift key to get the character (called a pipe, btw).
I believe the ANSI standard concatenation operator is: ||
SELECT id, name ||' ' || surname || ' ' || age AS info FROM users
It perfectly might be dependent of the database I would take a look for a concatenation function for the database you are running the select for.
Example. Mysql: CONCAT(name, surname, age).
You may need to cast the fields to a common type before concatenating. In T-SQL for example this would read.
Select id, Cast(name as varchar(50)) + ' ' + Cast(surname as varchar(50)) + ' ' +
Cast(age as varchar(3)) As info From Users
|| is used for this purpose.
Use it like
select name ||' ' ||surname ||' ' ||age as info from users
If you're using mysql or oracle then try CONCAT function:
SELECT id, CONCAT(name, ' ', surname, ' ', age) as info FROM users
That should work as is, but in general it is better not to do too much concatenation sql side if you can help it; rather return all the columns and concat them on the other end.
What are the data types you are using? You may need to CAST / CONVERT into (n)varchar
Make sure your data types are similar and convert any datatypes to string as necessary:
select id, (name + ' ' + surname + ' ' + convert(varchar(3),age)) as info from users
Works fine in most databases I know, although you probably have to CAST the age field to be TEXT. The exact method for doing this depends on the database you're using, which you did not specify.