Query same column twice but on different tables [duplicate] - sql

This question already has an answer here:
What I am doing wrong in this correlation query in oracle SqlDevelopper
(1 answer)
Closed 9 months ago.
I am trying to run a SQL query that looks like below.
For my purpose I need to query the same price list twice, but for different articles. To do this I have joined the same table twice but using two aliases. Then selected the same column but with the prefix of the alias. There are also nested queries at the bottom to the same table to get the correct date from said list.
The query worked as intended until I tried to add the second table of the price list, using aliases "MC1" and "MC2". Now I get SQL error 203 "Column %1 in more than one table".
The code passes all the syntax checks I made so I am at a loss currently.
Any help is appreciated.
(I was not allowed to post a picture directly in the threat so it is a link)
SQL Query Code snapshot

You need to prefix your columns that you are selecting with the table alias.
As an example, if I had this table
CREATE TABLE test_table
(
someid NUMBER,
someval VARCHAR2 (20)
);
I could query all of the columns like this
SELECT t1.someid,
t1.someval,
t2.someid,
t2.someval
FROM test_table t1 JOIN test_table t2 ON (t1.someid = t2.someid);

Related

Null values not being returned in Postgresql

I have two tables in Postgresql, which I need to perform the union taking the null values, to add other values in another column of the junction.
Table one:
I filtered by date, because this data is generated daily and I only need the current_date
Table two: All names.
In table two I have 9 names that are not found in table one.
When I try to perform the join, I only get the 9 names from table one as a result.
Trying with date from table one to current_date
But if I don't filter the date from table one, the null value is returned.
That is, the name that is in table two but not in table one.
What I need is to join the two tables and where there is no asset referring to the second table, fill it with 0 (zero).
In this part I understood that I must use COALESCE(vcm.ativo,0).
But first I need the names of the second table to appear as well.
The result should be like this:
If someone could help me, I'll be grateful.
As pointed out in a comment by the asker, the solution turned out to be
with todays_data as (
select vcm.cooperativa, vcm.ativo
from sga_bi.veiculos_coop_mensal as vcm
where data = current_date
)
select coop.nome, COALESCE(vcmm.ativo,0)
from sga.cooperativas as coop
left outer join todays_data as vcmm
on coop.nome = vcmm.cooperativa

Filtering a SELECT statement based on row data [duplicate]

This question already has answers here:
Query to list number of records in each table in a database
(23 answers)
Closed 7 years ago.
I'm trying to add a WHERE clause to a SELECT statement that checks to see if there is data in the table or if it was a 0-row table.
Basically, I'm trying to get this to work but obviously tables.NAME isn't a valid object.
SELECT NAME
FROM sys.tables
WHERE (SELECT Count(*)
FROM tables.NAME) <> 0
I don't want to have to create a temp table, declare a cursor and checking a value row by row, but I'm having a hard time thinking a bout how to do this otherwise.
Using a cursor is a suitable solution to this problem. You can't dynamically interpret a column from one table as a table name and simultaneously select from that table to see if it's empty like you're attempting to do. In fact you can't even select from a dynamic table without using dynamic SQL. See the documentation for FROM. You can either iterate over each table and check each, or you can query system tables that hold storage statistics to see if tables are empty.

SQL IN statement to extract for 100k records [duplicate]

This question already has answers here:
How to put more than 1000 values into an Oracle IN clause [duplicate]
(11 answers)
Closed 9 years ago.
I have a file SRQ which is having 10000 SRQ_ID which are unique.
I have one table(TABLE1) which is having 2 columns namely SRQ_ID,WORK_ID .
I needs to write a query which will search the table(TABLE1) for all the SRQ_ID's in the file SRQ and will display the output with corresponding WORK_ID.
I tried the below code. But IN clause is only applicable for 1000 records. How to run the same if I have 100k records?
select WO_ID
from TABLE1
where SRQ_ID in ('B6512DF0','5838FABC','EC5D804C','074DD65C')
Is there a reason you can't just do a join between the tables using SRQ_ID?
select wo_id from table1 join srq using srq_id
This will give you the work id for all rows that have a srq_id value in the srq table.
If the file s on the database server then you could access it as an external table, and join the two. Otherwise, I'd suggest bulk loading the codes into a global temporary table and performing the join against that.
In case you don't like to create a temporary table, you can use a nested table:
CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(20);
select WO_ID
from TABLE1
where SRQ_ID MEMBER OF VARCHAR_TABLE_TYPE('B6512DF0','5838FABC','EC5D804C','074DD65C');
But I don't know the limit for initializing a nested table. Oracle documentation says: "Because a nested table does not have a declared size, you can put as many elements in the constructor as necessary."

How to write an SQL query to get records based on the order they were entered in?(no date col) [duplicate]

This question already has answers here:
Is there a "Default Order By Column" in SQL Server?
(2 answers)
How to SELECT the last 10 rows of an SQL table which has no ID field?
(13 answers)
Closed 9 years ago.
I need to write a SQL query that returns records in the order in which they were entered in to a table.
I can't add a column to the table or change the table in any way. I can insert into and select from the table.
Say I execute three insert queries like
insert into x values(a,1);
insert into x values(d,4);
insert into x values(u,42);
when I select from the table x I need to get the records in this order.
a 1
d 4
u 42
The table has only two columns, both have nothing to do with date.
You can't do it without changing the table in some way.
When you select data from a table the order in which it is returned is non-deterministic on all the sql database engines I know and certainly in MSSQL server 2000+. To get the rows in a defined order you must include an ORDER BY clause and there is nothing you can specify to give the desired order.
Since you cannot change the schema, then this is game over.
Okay, (almost) nothing is impossible. You could periodically analyse the physical database file for changes and decode those into the information you require but, this would likely fail when multiple rows were inserted by one transaction.
I doubt you have the access or the inclination to do that.
You can't. The order returned is not deterministic without an order by clause, and you don't have any thing to order by

Update all rows of a single column

I'm dealing with two tables which have 2 columns, as listed under.
Table 1: table_snapshot
account_no | balance_due
Table 2: table_ paid
account_no | post_balance | delta_balance
I added a third column to table2 with the following command:
ALTER TABLE table_paid ADD delta_balance number(18);
I'm trying to use the following query, to update the new column ( delta_balance ) with the difference in balances between 1 and 2.
FYI, table_paid is a subset of table_snapshot. i,e., table 2 has only a few accounts present in table 1. I get an error saying : SQL Statement not properly ended. the query i'm using is:
UPDATE table_paid
SET table_paid.delta_balance = table_paid.post_balance - table_snapshot.balance_due
from table_paid, table_snapshot
WHERE table_paid.account_no = table_snapshot.account_no;
Appreciate if someone can correct my query.
Many thanks.
novice.
Oracle doesn't have the UPDATE ... FROM syntax that you're using from MS Sql Server (which, I believe, isn't ANSI anyway). Instead, when you need to do an update on a result set, Oracle has you create the resultset as a kind of inline view, then you update through the view, like so:
UPDATE ( SELECT tp.delta_balance
, tp.post_balance
, ts.balance_due
FROM table_paid tp
JOIN table_snapshot ts
ON tp.account_no = ts.account_no
)
SET delta_balance = post_balance - balance_due;
This is more "correct" than the answers supplied by Babar and palindrom, as their queries will update every row in table_paid, even if there are no corresponding rows in table_snapshot. If there is a 1-1 correspondance, you don't need to worry, but it's safer to do it with the inline view.
It's unclear from your example which table is the parent table, or (as I'm guessing) neither is the parent table and account_no is pointing to the primary key of another table (presumably account, or "table_account" by your naming conventions). In any case, it's clear that there is not a 1-1 correspondence in your table - 15K in one, millions in the other.
This could mean 2 things: either there are many rows in table_snapshot that have no corresponding row in table_paid, or there are many rows in table_snapshot for each row in table_paid. If the latter is true, your query is impossible - you will have multiple updates for each row in table_paid, and the result will be unpredictable; how will you know which of the "post_balance - balance_due" expressions will ultimately determine the value of a given delta_balance?
If you run my query, you will find this out quickly enough - you will get an error message that says, "ORA-01779: cannot modify a column which maps to a non key-preserved table". This error will appear based not on the data in the table (it may be okay), but based on the primary keys you have defined on the two tables. If the join condition you specify doesn't unambiguously result in a 1-1 relationship between the updated table and the rest of the join, based on the defined keys, you will get this error. It's Oracle's way of telling you, "You're about to screw up your data".
In the other answers here, you will only get an error (in that case, ORA-01427: single-row subquery returns more than one row) if you actually have data that would cause a problem; my version is more strict, so it may turn out that you will need to use the other versions.
And, as the others have said, you'll definitely want an index on account_no for the table_snapshot table. One on the table_paid wouldn't hurt either.
Try this
UPDATE table_paid
SET table_paid.delta_balance = table_paid.post_balance -
(SELECT table_snapshot.balance_due from table_snapshot WHERE table_paid.account_no =
table_snapshot.account_no);
UPDATE table_paid
SET table_paid.delta_balance = table_paid.post_balance - ( select balance_due from table_snapshot
WHERE table_paid.account_no = table_snapshot.account_no )