Join between two sql statements - sql

can i join between two sql satatmnet
example
select ID, NAME from tab1;
12|blabla
and
Select DESC from tab2;
vvvvvv
I want to display to
12|blabla|vvvvvv
I was try the the UNION
select ID, NAME from tab1;
UNION
Select DESC from tab2;
but the result was
12|blabla
12|vvvvv
any help !!

You could do this:
select t1.*, t2.*
from (select ID, NAME from tab1) t1 cross join
(Select "DESC" from tab2) t2;
DESC is a SQL reserved word, so you need to escape it. Double quotes are one way of doing that.

Dont use UNION but instead use JOIN

Related

Hive Subquery in SELECT

I have a query like
SELECT name, salary/ (SELECT max(money) from table_sal) FROM table_a;
I get an error saying
Unsupported SubQuery Expression Invalid subquery. Subquery in SELECT could only be top-level expression
Is there a way to resolve this?
Does this work with a CROSS JOIN?
SELECT name, salary / s.max_money
FROM table_a CROSS JOIN
(SELECT max(money) as max_money from table_sal) s
You can also do this as below, please let me know if it works for you.
Select t1.name
, t1.salary/T2.max_money
from
(SELECT name
, salary, 1 as dummy
from table_a ) t1
Join
(SELECT max(money) as max_money
, 1 as dummy
from table_sal) t2
on t1.dummy = t2.dummy ;

how can we select data from two or more tables if similar data is not present in both tables(without join)

I need solution for this type query.Means this query is not real but I need to fetch data like this:(except join and union)
select a b,c
from (table1 or table2)
where name="rohit";
it's simple to do with union
select *
from t1
where t1.name='a'
union (all)
select *
from t2
where t2.name='a'
If union and join is not allowed you can try select both table and create kind of union via GROUP BY trick. Like this
select *
from t1, t2
where t1.name='a' or t2.name='a'
group by (case t1.name
when 'a' then CONCAT('t1',t1.id)
else CONCAT('t2',t2.id) end case)
Haven't tested though. sqlfiddle.com somehow doesn't work showing errors when I try to execute a query like this

How to use order by and rownum without subselect?

I need to build a query with a order by and rownum but without use a sublect.
It is needed to get the first row of the query ordered.
In other words, I want the result of
select * from (
SELECT CAMP1,ORDERCAMP
FROM TABLENAME
ORDER BY ORDERCAMP) where rownum=1;
but whithout use a subselect. Is it possible?
I have a Oracle 11. You could say this is my whole query:
SELECT T1.CAMP_ID,
T2.CAMP
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
FROM TABLE1 T1,
TABLE2 T2
WHERE T1.FK_TO_T2=T2.PK;
The subquery returns more than one row, and I cant use another subquery like
SELECT T1.CAMP_ID,
T2.CAMP
(SELECT *
FROM
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
WHERE ROWNUM=1
)
FROM TABLE1 T1,
TABLE2 T2
WHERE T1.FK_TO_T2=T2.PK;
SELECT CAMP1,ORDERCAMP FROM TABLE2 ORDER BY ORDERCAMP
Because the T1.CAMP_ID is an invalid identifier in the third level subquery.
I hope I have explained myself enough.
Your current query (without the invalid ORDER BY) gets ORA-01427: single-row subquery returns more than one row. You can nest subqueries, but you can only refer back one level when joining; so if you did:
SELECT T1.CAMP_ID, T2.CAMP,
(SELECT CAMP FROM
FROM
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
WHERE ROWNUM = 1)
FROM TABLE1 T1, TABLE2 T2 WHERE T1.FK_TO_T2=T2.PK;
... then you would get ORA-00904: "T1"."CAMP_ID": invalid identifier. Hence your question, presumably.
What you could do instead is join to the third table, and use the analytic ROW_NUMBER() function to assign the row number, and then use an outer select wrapped around the whole thing to only find the records with the lowest ORDERCAMP:
SELECT CAMP_ID, CAMP, OT_CAMP
FROM (
SELECT T1.CAMP_ID, T2.CAMP, OT.CAMP AS OT_CAMP,
ROW_NUMBER() OVER (PARTITION BY T1.CAMP_ID ORDER BY OT.ORDERCAMP) AS RN
FROM TABLE2 T2
JOIN TABLE1 T1 ON T1.FK_TO_T2=T2.PK
JOIN OTHERTABLE OT ON OT.FK_TO_TABLE1=T1.CAMP_ID
)
WHERE RN = 1;
The ROW_NUMBER() can partition on the T1.CAMP_ID primary key value, or anything else that is unique.
SQL Fiddle demo, including the inner query run on its own so you can see the RN numbers assigned before the outer filter is applied.
Another approach is to use the aggregate KEEP DENSE_RANK FIRST function
SELECT T1.CAMP_ID, T2.CAMP,
MAX(OT.CAMP) KEEP (DENSE_RANK FIRST ORDER BY OT.ORDERCAMP) AS OT_CAMP
FROM TABLE2 T2
JOIN TABLE1 T1 ON T1.FK_TO_T2=T2.PK
JOIN OTHERTABLE OT ON OT.FK_TO_TABLE1=T1.CAMP_ID
GROUP BY T1.CAMP_ID, T2.CAMP;
Which is a bit shorter and doesn't need an inner query. I'm not sure if there's any real advantage of one over the other.
SQL Fiddle demo.
In the most recent version of Oracle, you can do:
SELECT CAMP1, ORDERCAMP
FROM TABLENAME
ORDER BY ORDERCAMP
FETCH FIRST 1 ROWS ONLY;
Otherwise, I think you need a subquery of some sort.
You could use LIMIT or SELECT TOP 1
SELECT CAMP1, ORDERCAMP FROM TABLENAME ORDER BY ORDERCAMP LIMIT 1

ODBC Firebird Sql Query - Syntax

Trying to get an slightly more complex sql statement structured but can't seem to get the syntax right. Trying to select counts, of various columns, in two different tables.
SELECT
SUM(ColumninTable1),
SUM(Column2inTable1),
COUNT(DISTINCT(Column3inTable1))
FROM TABLE1
This works, however I can't for the life of me figure out how to add in a COUNT(DISTINCT(Column1inTable2) FROM TABLE2 with what syntax.
There are several solutions you can take:
Disjunct FULL OUTER JOIN
SELECT
SUM(MYTABLE.ID) as theSum,
COUNT(DISTINCT MYTABLE.SOMEVALUE) as theCount,
COUNT(DISTINCT MYOTHERTABLE.SOMEOTHERVALUE) as theOtherCount
FROM MYTABLE
FULL OUTER JOIN MYOTHERTABLE ON 1=0
UNION two queries and leave the column for the other table null
SELECT
MAX(theSum) as theSum,
MAX(theCount) as theCount,
MAX(theOtherCount) AS theOtherCount
FROM (
SELECT
SUM(ID) as theSum,
COUNT(DISTINCT SOMEVALUE) as theCount,
NULL as theOtherCount
FROM MYTABLE
UNION ALL
SELECT
NULL,
NULL,
COUNT(DISTINCT SOMEOTHERVALUE)
FROM MYOTHERTABLE
)
Query 'with a query per column' against a single record table (eg RDB$DATABASE)
SELECT
(SELECT SUM(ID) FROM MYTABLE) as theSum,
(SELECT COUNT(DISTINCT SOMEVALUE) FROM MYTABLE) as theCount,
(SELECT COUNT(DISTINCT SOMEOTHERVALUE) FROM MYOTHERTABLE) as theOtherCount
FROM RDB$DATABASE
CTE per table + cross join
WITH query1 AS (
SELECT
SUM(ID) as theSum,
COUNT(DISTINCT SOMEVALUE) as theCount
FROM MYTABLE
),
query2 AS (
SELECT
COUNT(DISTINCT SOMEOTHERVALUE) as theOtherCount
FROM MYOTHERTABLE
)
SELECT
query1.theSum,
query1.theCount,
query2.theOtherCount
FROM query1
CROSS JOIN query2
There are probably some more solutions. You might want to ask yourself if it is worth the effort of coming up with a (convoluted, hard to understand) single query to get this data were two queries are sufficient, easier to understand and in the case of large datasets: two separate queries might be faster.
In this case all "count" would return the same value.
Try to do the same using sub queries:
Select
(Select count (*) from Table1),
   (Select count (*) from table2)
from Table3

select first N distinct rows without inner select in oracle

I have something like the following structure: Table1 -> Table2 relationship is 1:m
I need to perform queries similar to the next one:
select Table1.id from Table1 left outer join Table2 on (Table1.id1 = Table2.id2) where Table2.name like '%a%' and rownum < 11
i.e. I want first 10 ids from Table 1 which fulfils conditions in Table2. The problem is that I've to use distinct, but the distinct clause applies after 'rownum < 11', so the result could be e.g. 5 records even if their number is more than 10.
The apparent solution is to use the following:
select id from ( select Table1.id from Table1 left outer join Table2 on (Table1.id1 = Table2.id2) where Table2.name like '%a%' ) where rownum < 11
But I'm afraid of performance of such a query. If Table1 contains about 300k records, and Table2 contains about 700k records, wouldn't such a query be really slow?
Is there another query, but without inner select? Unluckily, I want to avoid using inner selects.
Unluckily, I want to avoid using inner
selects
With having the WHERE clause on TABLE2, you are filtering the select to an INNER JOIN (ie. since Table2.name IS null <> Table2.name like '%a%' you will only get results where the join is INNER to one another. Also, the %a% without a function based index will result in a full table scan on each iteration.
but #lweller is completely correct, to do the query correctly you will need to use a subquery. keep in mind, without an ORDER BY you have no guarantee of the order of your top X records (it may always 'appear' that the values conform to the primary key or whatnot, but there is no guarantee.
WITH TABLE1 AS(SELECT 1 ID FROM DUAL
UNION ALL
SELECT 2 ID FROM DUAL
UNION ALL
SELECT 3 ID FROM DUAL
UNION ALL
SELECT 4 ID FROM DUAL
UNION ALL
SELECT 5 ID FROM DUAL) ,
TABLE2 AS(SELECT 1 ID, 'AAA' NAME FROM DUAL
UNION ALL
SELECT 2 ID, 'ABB' NAME FROM DUAL
UNION ALL
SELECT 3 ID, 'ACC' NAME FROM DUAL
UNION ALL
SELECT 4 ID, 'ADD' NAME FROM DUAL
UNION ALL
SELECT 1 ID, 'BBB' NAME FROM DUAL
) ,
sortable as( --here is the subquery
SELECT
Table1.ID ,
ROW_NUMBER( ) OVER (ORDER BY Table2.NAME NULLS LAST) ROWOverName , --this wil handle the sort
table2.name
from
Table1
LEFT OUTER JOIN --this left join it moot, pull the WHERE table2.name into the join to have it LEFT join as expected
Table2
on
(
Table1.id = Table2.id
)
WHERE
Table2.NAME LIKE '%A%')
SELECT *
FROM sortable
WHERE ROWOverName <= 2;
-- you can drop the ROW_NUMBER( ) analytic function and replace the final query as such (as you initially indicated)
SELECT *
FROM sortable
WHERE
ROWNUM <= 2
ORDER BY sortable.NAME --make sure to put in an order by!
;
You don't need DISTINCT here at all, and there is nothing bad in subqueries as such.
SELECT id
FROM Table1
WHERE id IN
(
SELECT id
FROM Table2
WHERE name LIKE '%a%'
)
AND rownum < 11
Note that the order is not guaranteed. To guarantee order, you have to use a nested query:
SELECT id
FROM (
SELECT id
FROM Table1
WHERE id IN
(
SELECT id
FROM Table2
WHERE name LIKE '%a%'
)
ORDER BY
id -- or whatever else
)
WHERE rownum < 11
There is no way to do it without nested queries (or the CTE).
For me there is no reason to be afraid of performance. I think the sub select ist the best way to solve your problem. And if you want don't trust me, take a look at explain plan of your query and you will see that it behave not so bad as you might think.