Select return more value than one to main select - sql

Can you please help me? I have one main (SELECT), where I'm using more next select commands but inferior select return me more value than one.
SELECT table1.column1
AS table.refer, table2.column2 AS table.value,
--Here is my problem:
(select count(table.column.id) FROM table1
left outer join table1 on table1.column1 = table.column
LEFT outer join table2 on table2.column2 = table1.column1
LEFT OUTER JOIN table3 on table3.column3 = table2.column2
WHERE table1.column1 = (23212 " This value contains more data) AND table2.column2 = value AND YEAR(table1.column1) = YEAR(GETDATE() GROUP BY table.refer)
FROM table1 left outer join table1 on table1.column1 = table.column
LEFT outer join table2 on table2.column2 = table1.column1
LEFT OUTER JOIN table3 on table3.column3 = table2.column2
WHERE table1.name1 in (23210, 23211, 23212, 4882525, 67735166, 74605160) AND table2.name2 in (15739, 15744, 15743, 15741, 15735, 15745)
GROUP BY table.refer, table.value
Important value from main select is table.refer. I need take only one table.refer for second select. But for all data.
I check cursor function for this or create new table for this select data or field[] but I don't know how do it. Please help me.

So, part of the problem is that you have a Group By int the subquery (the "inferior select). This would allow the select to have a single column (count(table.column.id)) but multiple rows for that column, one for each table.refer. If you think about it, you're asking for the results of the sub select to be a field in higher select. So it can only return a single value.
So I think you may want to just remove the Group By. This would return a single Count result for the sub query.
If that is not what you wanted but are expecting multiple values, then the subquery as a field would not be the way to go and would need better description of what you're trying to achieve.

Related

SQL join three tables, get value from second, if null, then from thrid

I am using SQL Server 2019.
I have three tables.
I want to get the value from second table using inner join, but if the value in second table does not exist, then the value should be retrieved from third table.
Enter image description here
I came up with the SQL below, but this returns no data.
Select
Table1.ID,
Case
When Table2.Value2 Is Not Null Then Table2.Value2
Else Table3.Value3
End as Value
from Table1
Inner Join Table2 On Table1.ID = Table2.ID2
Inner Join Table3 On Table1.ID = Table3.ID3
I googled, but I could not reach the answer.
Any help is appreciated, thank you.
We can use the COALESCE() function here:
SELECT t1.ID, COALESCE(t2.Value2, t2.Value3) AS Value
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.ID = t2.ID2
LEFT JOIN Table3 t3 ON t1.ID = t3.ID3;
A left, rather than inner, join is required in the event that the second table does not have a matching ID. In this case, the query retains all IDs from the first table and gives the chance for a match from the third table.

Create a SQL Query that compares two tables and return an indicator if value is contained in Table 1 but not in Table2

I'm working on the below query.
SELECT *
FROM eg_table1
LEFT JOIN eg_table2 ON eg_table1.part_id = eg_table2.PRODNO
WHERE eg_table1.part_id LIKE "%ARG1%" AND eg_table2.CCI_PROJECT_ID LIKE '%ARG2%'
It works fine, however, when ARG1 is not contained in table2 it doesn't return anything. Could anyone help me find a way to add a functionality to this query to show ARG1 and an indicator that the value is in table 1 but not in table 2?
When selecting records that are contained in Table1 and not in Table2, this query is usually written that:
select * from Table1 t1
left join Table2 t2 on t2.example_id = t1.example_id
where t2.id is null
And be careful: When using left join, so joining conditions should be after the on command, not in the where clause.
If you want to show records that contained ARG1 in Table1 and not contained in Table2, let's change your query:
SELECT *
FROM eg_table1 t1
LEFT JOIN eg_table2 t2 ON
t1.part_id = t2.PRODNO and
t2.CCI_PROJECT_ID LIKE '%ARG1%'
WHERE
t1.part_id LIKE "%ARG1%" and
t2.PRODNO is null
How will this query work? I explain:
Table1 will be filtered by this condition: t1.part_id LIKE "%ARG1%"
Table2 will be joined to Table1 by these conditions: (t1.part_id = t2.PRODNO and t2.CCI_PROJECT_ID LIKE '%ARG1%')
Query will be shown records that t1.part_id LIKE "%ARG1%" = true and (t1.part_id = t2.PRODNO and t2.CCI_PROJECT_ID LIKE '%ARG1%') = false

DELETE duplicates with subquery from 2 tables in MS Access

I have two tables with same structure that can have duplicated records, I want to identify which ones from table 2 already exists in table 1 and delete them from table 2. The following SELECT returns the duplicated records I want to delete. None of these tables have a primary key, so I need to do multiple 'ON' to identify unique records.
SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3;
Then I insert this as a subquery for the DELETE:
DELETE FROM table2
WHERE table2.column1 IN
(SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);
When running this query I get the following error:
You have written a query that can return more than one field without using the reserved word EXISTS in the FROM clause of the main query. Correct the SELECT instruction of the subquery to request a single field.
I also tried this way, but it deletes all the records from table 2, not only the result of the subquery:
DELETE FROM table2
WHERE EXISTS
(SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);
This is the first solution I came up with, but I'm wondering if it wouldn't be easier to do in MS Access inserting into table1 all the records from table2 that doesn't match, and then delete table2.
All sugestions will be appreciated :)
Take the advice of the error message and try using exists logic:
DELETE
FROM table2 t2
WHERE EXISTS (SELECT 1 FROM table1 t1
WHERE t1.column1 = t2.column1 AND
t1.column2 = t2.column2 AND
t1.column3 = t2.column3);
The problem with your current exists attempt is that the query inside the EXISTS clause always has a result set, and that result set is independent of the outer delete call. So, all records get deleted.
I think you're just missing the specific column in your subquery.
This should work better :
DELETE FROM table2
WHERE table2.column1 IN
(SELECT V.column1
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);

Oracle sql MERGE INTO with a single where clause

I have the following SQL code (this is how much I've got so far):
MERGE INTO SCHEMA1.TABLE_1 table1 USING
(
SELECT DISTINCT table2.column1,
view1.column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
) t2 ON (table1.column3 = t2.column1 )
WHEN MATCHED THEN
UPDATE
SET table1.column4 = t2.column2;
The following is the definition of VIEW_1 :
CREATE VIEW SCHEMA_2.VIEW_1
AS (SELECT
SCHEMA_2.TABLE_1.COLUMN_1,
SCHEMA_2.TABLE_2.COLUMN_1,
SCHEMA_2.TABLE_2.COLUMN_2,
SCHEMA_2.TABLE_2.COLUMN_3,
SCHEMA_2.TABLE_5.COLUMN_1,
SCHEMA_2.TABLE_6.COLUMN_1,
SCHEMA_2.TABLE_6.COLUMN_2,
SCHEMA_2.TABLE_6.COLUMN_3,
SCHEMA_2.TABLE_6.COLUMN_4,
SCHEMA_2.TABLE_7.COLUMN_1,
SCHEMA_2.TABLE_7.COLUMN_2,
SCHEMA_2.TABLE_8.COLUMN_1
FROM SCHEMA_2.TABLE_1
INNER JOIN SCHEMA_2.TABLE_2
ON SCHEMA_2.TABLE_1.COLUMN_1 = SCHEMA_2.TABLE_2.COLUMN_2
INNER JOIN SCHEMA_2.TABLE_5
ON SCHEMA_2.TABLE_1.COLUMN_4 = SCHEMA_2.TABLE_5.COLUMN_3
LEFT OUTER JOIN SCHEMA_2.TABLE_6
ON SCHEMA_2.TABLE_2.COLUMN_2 = SCHEMA_2.TABLE_6.COLUMN_4
LEFT OUTER JOIN SCHEMA_2.TABLE_7
ON SCHEMA_2.TABLE_2.COLUMN_1 = SCHEMA_2.TABLE_8.COLUMN_5
);
But I'm getting the below error message:
Error report -
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 - "unable to get a stable set of rows in the source tables"
*Cause: A stable set of rows could not be got because of large dml
What causes the error? Where to change in the code to make it work?
Thanks for helping out!
For this example your problem is definitely in the USING subquery. This query produces more than one value of table2.column1:
SELECT DISTINCT table2.column1,
view1.column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
So the ON clause will match the same row(s) in table1 more than once:
ON (table1.column3 = t2.column1 )
Oracle cannot figure out which value of t2.column2 should be used in the UPDATE, so it hurls ORA-30926.
Using distinct in the subquery doesn't help because that gives permutations of all the columns. You need to write a subquery which will produce unique values of t2.column1 across all rows, or add another identifying column(s) to generate a unique key you can join to table1.
In my experience, this error is returned, not only when the USING clause returns more than one row for a row in the MATCH table, but also frequently when it cannot be sure that only one row will be returned (even if there are no actual cases of multiple rows being returned). To force the parser to accept the query in cases like this, I usually resort to using a GROUP BY on the MATCH..ON column(s).
MERGE INTO SCHEMA1.TABLE_1 table1 USING
(
SELECT table2.column1,
MAX(view1.column2) as column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
GROUP BY table2.column1
) t2 ON (table1.column3 = t2.column1 )
WHEN MATCHED THEN
UPDATE
SET table1.column4 = t2.column2;

SQL aggregate function returning inflated values on joined table

I'm breaking my head here where I'm going wrong.
The following query:
SELECT SUM(table1.col1) FROM table1
returns value x.
And the following query:
SELECT SUM(table1.col1) FROM table2 RIGHT OUTER JOIN table1 ON table2.ID = table1.ID
returns value y. (I need the Join for the other data of table2). Why is the 2nd example returning a different value than in the first?
Make life easier on yourself, your colleagues that will support your code, and your clients by temporarily ignoring the existence of RIGHT OUTER JOIN. Use Table1 as the "from table" instead of table2.
Then, If aggregating, you will often find it necessary to do this BEFORE joining, so that the numbers are accurate. e.g.
SELECT T1.SUMCOL1
FROM (
SELECT id, SUM(col1) as SUMCOL1 FROM Table1 GROUP BY id
) T1
LEFT OUTER JOIN table2 T2 on T1.id = T2.ID
Obvious answer is because table2 is many to table1's one. That is, there are multiple rows in table2 for one id in table1. You may also be eliminating rows from table1 if the id isn't present in table2.
Compare:
SELECT COUNT(*) FROM table1
To:
SELECT COUNT(*) FROM table2 RIGHT OUTER JOIN table1 ON table2.ID = table1.ID
If you get different results, you're aggregating duplicates or eliminating rows from table1.
If you want to avoid this, you'll need to use a subquery.