Invalid identifier error on field created with select statement - sql

Why sql bellow don't work?
select
a.field1, a.field2, a.field3,
(select count(*)
from table2 b
where b.field1 = a.field1
) as field4,
(select count(*)
from table3 b
where b.field1 = a.field1
) as field5,
(select count(*)
from table4 b
where b.field1 = a.field1
) as field6,
from table1 a
order by field4
Oracle says: ORA-00904: "field4": invalid identifier

try to wrap it up
select * from
(
select
a.field1, a.field2, a.field3,
(select count(*)
from table2 b
where b.field1 = a.field1
) as field4,
(select count(*)
from table3 b
where b.field1 = a.field1
) as field5,
(select count(*)
from table4 b
where b.field1 = a.field1
) as field6,
from table1 a
)
order by field4

Related

mongodb equivalent to sql WITH clause?

I want to query something with SQL's WITH clause, query:
with t1 as(
select field1, field2, calculatedField
from table1
),
t2 as (
select field1, field2, calculatedField
from table 2
)
select a.*, b.*
from t1 as a
left join t2 as b on a.field1 = b.field1
how can I achieve this in mongodb? i can't find an operator in mongodb for WITH

SQL select result from two fields where equal to same search result

Currently SQL statement as below:
SELECT result FROM tableA WHERE
field1 = (SELECT x FROM tableB WHERE field3 = "XXX") OR
field2 = (SELECT x FROM tableB WHERE field3 = "XXX");
Can simplify the two select statementSELECT x FROM tableB WHERE field3 = "XXX" ?
Have using JOIN and currently the statement as below:
SELECT resultB from tableA a join
tableB b on
b.field4 = a.field1 or
b.field4 = a.field2 where
b.field3 = "XXX";
Further on, "XXX" is from below SQL statement:
SELECT DISTINCT(resultA) FROM tableC c WHERE c.field5 is false;
How to combine this to having result as below:
resultA(1), resultB(1)
resultA(2), resultB(2)
resultA(3), resultB(3)
...
Thanks.
You can join the tables.
SELECT
a.result
FROM tableA a
join tableB b on b.x = a.field1 or b.x = a.field2
where b.field3 = 'XXX'
https://www.w3schools.com/sql/sql_join.asp
You can do it with EXISTS:
SELECT a.result
FROM tableA a
WHERE EXISTS (
SELECT 1
FROM tableB b
WHERE b.field3 = 'XXX' AND b.x IN (a.field1, a.field2)
)
Although you can "simplify" the logic, if you care about performance that is probably not a good route. Instead, I would suggest using exists twice:
SELECT a.result
FROM tableA a
WHERE EXISTS (SELECT 1
FROM tableB b
WHERE b.x = a.field1 AND b.field3 = 'XXX'
) OR
EXISTS (SELECT 1
FROM tableB b
WHERE b.x = a.field2 AND b.field3 = 'XXX'
);
This can make use of an index on tableB(x, field3).

Converting a PostgreSQL query with IN / NOT IN to JOINs

I currently have two tables with the same structure. Table A (as an example) has 10,000 rows, table B has 100,000 rows. I need to obtain the rows that are in Table B that are not in Table A, but only if certain fields are the same (and one is not).
Right now, the query is something like:
select *
from tableA A
where (A.field1, A.field2) in (select field1, field2 from tableB B)
and A.field3 not in (select field3 from B)
This works, but probably a better performant solution could be done with JOINs. I have tried to do it but all I get is a very huge list of duplicated rows. Could someone point me in the right direction?
Based on your current query this is what it translates to as joins:
select *
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
A faster query would be:
select A.pk
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
group by A.pk
This would give you the rows you need to add to tableB because they aren't found.
Or you can just get the fields you want to pull over:
select A.field1, A.field2, A.field3
from tableA A
inner join tableB B on A.field1 = B.field1 and A.field2 = B.field2
left outer join tableB C on A.field3 = C.field3
where c.field3 is null
group by A.field1, A.field2, A.field3
[NOT] EXISTS is your friend:
SELECT *
FROM tableA A
WHERE EXISTS ( SELECT * FROM tableB B
WHERE A.field1 = B.field1
AND A.field2 = B.field2
)
AND NOT EXISTS ( SELECT * FROM tableB B
WHERE A.field3 = B.field3
);
Note: if the joined columns are NOT NULLable, the [NOT] EXISTS() version will behave exactly the same as the [NOT] IN version
Reading the question text again (and again):
I need to obtain the rows that are in Table B that are not in Table A, but only if certain fields are the same (and one is not).
SELECT *
FROM tableB B
WHERE EXISTS ( SELECT * FROM tableA A
WHERE A.field1 = B.field1
AND A.field2 = B.field2
AND A.field3 <> B.field3
);

Select Distinct returning multiple rows

I've got a query that is:
SELECT DISTINCT a.field1, a.field2, a.field3, b.field1, b.field2, a.field4
FROM table1 a
JOIN table2 b ON b.fielda = a.fieldb
WHERE a.field1 = 'xxxx'
I run this and it returns three xxxx rows. I need all of the information listed above with the first field being distinct. Do I have the correct syntax for this?
In Postgres, you can use distinct on:
select distinct on (a.field1) a.field1, a.field2, a.field3, b.field1, b.field2, a.field4
from table1 a join
table2 b
on b.fielda = a.fieldb
where a.field1 = 'xxxx'
order by a.field1;
In either Postgres or SQL Server, you can use row_number():
select ab.*
from (select a.field1, a.field2, a.field3, b.field1, b.field2, a.field4,
row_number() over (partition by a.field1 order by a.field1) as seqnum
from table1 a join
table2 b
on b.fielda = a.fieldb
where a.field1 = 'xxxx'
) ab
where seqnum = 1;
Or, since you only want one row, you can use limit/top:
select a.field1, a.field2, a.field3, b.field1, b.field2, a.field4
from table1 a join
table2 b
on b.fielda = a.fieldb
where a.field1 = 'xxxx'
limit 1;
In SQL Server:
select top 1 a.field1, a.field2, a.field3, b.field1, b.field2, a.field4
from table1 a join
table2 b
on b.fielda = a.fieldb
where a.field1 = 'xxxx';
One option is to use row_number():
with cte as (
select distinct a.field1, a.field2, a.field3, b.field1, b.field2, a.field4,
row_number() over (partition by a.field1 order by a.field1) rn
from table1 a
join table2 b on b.fielda = a.fieldb
where a.field1 = 'xxxx'
)
select *
from cte
where rn = 1
But you need to define which record to take. This orders by field1 which essentially will take a random record...
As you can read from your comments, DISTINCT cannot work for you. It gives you distinct rows. What you need instead is an aggregation, so as to get from three records to only one.
So the first comment you got (by sgeddes) is already the answer you need: "what values should the other columns have?". How shall the dbms know? You didn't tell it.
One row per field1 usually means GROUP BY field1. Then for every other field decide what you want to see: The maximum of field2 maybe? The minimum of field3? The avarage of field4?
select a.field1, max(a.field2), min(a.field3), count(b.field1), sum(b.field2), avg(a.field4)
from table1 a
join table2 b on b.fielda = a.fieldb
where a.field1 = 'xxxx'
group by a.field1;

Join SQL query results inside stored procedure

I need to join result sets inside a stored procedure, I tried this query but it is incorrect.
SELECT * FROM (SELECT Field1, Field2 FROM Table1 WHERE Field4='val1') A
INNER JOIN
SELECT * FROM (SELECT Field1, Field3 FROM Table1 WHERE Field4='val2') b
ON A.Field1 = B. Fileld1
How to join resulting tables inside a stored procedure?
try this:
you don't have to use SELECT * FROM twice..
SELECT * FROM
(SELECT Field1, Field2 FROM Table1 WHERE Field4='val1') A
INNER JOIN
(SELECT Field1, Field3 FROM Table1 WHERE Field4='val2') b
ON A.Field1 = B. Fileld1
You are doing some this like this (Just for an example):
SELECT * FROM Table1 A
INNER JOIN
SELECT * FROM Table2 B
ON A.FIELD1 = B.FIELD2
Which is wrong. Because you don't need to write SELECT * FROM twice. Correct one is:
SELECT * FROM Table1 A
INNER JOIN
Table2 B
ON A.FIELD1 = B.FIELD2
So your query should be(Including Create procedure):
CREATE PROCEDURE testJoining
AS
SELECT * FROM
(SELECT FIELD1, Field2 FROM Table1 WHERE Field4='VAL1') A
INNER JOIN
(SELECT FIELD1, Field3 FROM Table1 WHERE Field4='VAL2') B
ON A.FIELD1 = B.FIELD1
GO
See this fiddle.
Other way to select data from the same table is:
SELECT A.Field1,A.Field2,B.Field3 FROM Table1 A
INNER JOIN
Table1 B
ON A.FIELD1 = B.FIELD1
WHERE A.Field4='VAL1'
AND B.Field4='VAL2'
See this fiddle
Maybe this would help
With cte_sample AS ( SELECT Field1, Field2 FROM Table1
WHERE Field4='val1' )
SELECT Field1, Field3 FROM Table1 AS a
INNER JOIN cte_sample ON a.Field1 = cte_sample.Field1 AND
WHERE a.Field4='val2'