SQL Simple Query From Multiple Tables - sql

I would appreciate if anyone can give me a hand with this question
I have 4 SQL tables. Open, High, Low and Close.
Each have 2 columns called [Date],[Price].
The dates are the same - but Price is a number and is different.
How can we make a query where the results are as follows
[Date],[Open.Price],[High.Price],[Low.Price],[Close.Price]

SELECT Open_table.date,Open_table.Price,High_table.Price,low_table.Price,
Close_table.Price
FROM Open_table
JOIN High_table ON Open_table.date = High_table.date
JOIN low_table ON Open_table.date = low_table.date
JOIN Close_table ON Open_table.date = Close_table.date

You could try joining on date:
SELECT t1.[Date],
t1.[Price] AS [Open.Price],
t2.[Price] AS [High.Price],
t3.[Price] AS [Low.Price],
t4.[Price] AS [Close.Price]
FROM Open t1
INNER JOIN High t2
ON t1.[Date] = t2.[Date]
INNER JOIN Low t3
ON t2.[Date] = t3.[Date]
INNER JOIN Close t4
ON t3.[Date] = t4.[Date]

I found another way of doing so after I posted this question
SELECT
EuropeOpen.[Date],EuropeOpen.[OCDO LN],EuropeHigh.[Date],EuropeHigh.[OCDO LN],EuropeLow.[Date],EuropeLow.[OCDO LN],
EuropeClose.[Date],EuropeClose.[OCDO LN]
FROM EuropeOpen,EuropeHigh,EuropeLow,EuropeClose
// In case you need any conditions
WHERE....

Related

ORACLE SQL - Get limited rows with maximum values in a column with rownum but without a subquery

I have a table in Oracle DB which consists of products and stock. I want to get a limited number of products in output (say 10 products) with maximum stock. There are also other conditions that I would check which involves inner join with multiple tables.
This query randomly selects 10 products from the table then sorts it, so its not helpful:
Select prod_code, stock from producttable where rownum < 10
--and lots of other conditions
order by stock desc
I searched and found this below method. But this runs forever because the inner query is a full table output:
Select * from (Select prod_code, stock from producttable where
-- lots of other conditions
order by stock desc) where rownum < 10
Can someone please help me find a way to do this accurately and efficiently ?
Following is the query used -
SELECT * from (SELECT
wbob.p1
FROM t1 wbob
Inner join t2 wboc on wboc.p2 = wbob.p2
Inner join t3 wboa on wboa.p2 = wbob.p2
Inner join t4 mfa on mfa.p3 = wbob.p4
Left outer join t5 mfb on mfb.p3 = wbob.p4
Inner join t6 mfc on mfc.p3 = wbob.p4
Inner join t7 mfd on mfd.p3 = wbob.p4
Inner join t8 mfg on mfg.p3 = wbob.p4
Inner join t9 sta on sta.p5 = wbob.p4
Inner join t10 stb on stb.p6 = sta.p6
Inner join t11 stc on stc.p7 = stb.p7
WHERE
wboa.stock > '0'
and wboa.p8 in ('14','198')
and wboc.p9 = '187'
and mfd.p10 > 0
and stb.p11 > 0
and trim(mfa.p12) = 'ACT'
and mfa.p13 = 'N'
and trim(stc.p7) = '3333'
and mfc.p14 = 11
and mfc.p15 = 3333
and mfg.p16 = 1
and mfc.p17 = 'Y'
and mfd.p18 = 'N'
and mfa.p19 = 'W'
and wbob.p1 NOT IN (Select wbob1.p1
from t1 wbob1
inner join t3 wboa1 ON wboa1.p2 = wbob1.p2
where wboa1.stock > '0'
and wboa1.p8 NOT IN ('14','198'))
and (wbob.p4 NOT IN (Select mfb7.p3 from t5 mfb7) OR wbob.p4 IN (Select mfb8.p3 from t5 mfb8
where mfb8.p20 = 0))
ORDER BY stb.p11 DESC) where rownum < 10
Explain plan
You can do this in 12c without a subquery using fetch first n rows only
Select prod_code, stock
from producttable
where ...
--and lots of other conditions
order by stock desc
fetch first 10 rows only
However, this will not solve the problem you are complaining about which is the performance of the query and how the inner query is a full table output. This is actually necessary and this solution will do the same. In order to sort stock to get the top stock items, the db will have to look at and sort all the possible rows. How else can you get the top items without looking at all of them? There might be ways to improve this, like an index on the stock value, but I wouldn't recommend that without knowing detail your data model.
You need a subquery:
select p.*
from (Select prod_code, stock
from producttable
order by stock desc
) p
where rownum < 10;
For performance, you want an index on producttable(stock, prod_code). The subquery isn't causing the performance issue; the lack of index is.

4 Tables Joining in SQL

I have some preps/views which im using in my final select clause in the following way :
select .......
from gr
full outer join go
on gr.ART_CONC=go.ART_CONC and
gr.pt=go.pt and
gr.p_act=go.p_act and
gr.month_id=go.month_id and
gr.art_desc=go.art_desc
Now i want to also include the following in my select clause, but im confused how the syntax and join would really go
sim ab join prep1
on ab.fp_num3 = article_num AND
substr(ab.fp_num2,-2,2) = substr(pt10,-2,2)
where fp_data_kind='SEC PFE_ND_GO'
and fp_data_valid_from between to_date(:par_date_from, 'YYYY.MM.DD HH24:MI:SS') and to_date(:par_date_to, 'YYYY.MM.DD HH24:MI:SS')
Note : sim, prep1,gr and go are 4 tables/preps that already exist.
Thanks in Advance !
In this, table1/2/3/4 are your tables. join_val's are the values you are joining on. I did not fully understand your question or what you wanted so this one way to go about doing 4 joins.
select t1.something1
,t1.something2
,t1.something3
,t2.something1
,t2.something2
,t2.something3
,t3.something1
,t3.something2
,t3.something3
,t4.something1
,t4.something2
,t4.something3
from table1 t1
full outer join table2 t2
on t1.join_val = t2.join_val
......
full outer join table3 t3
on t1.join_val = t3.join_val
......
full outer join table4 t4
on t.join_val = t3.join_val

The multi-part identifier could not be bound - SQL Server 2014

I am trying to solve the error in the below query
Yes I have checked many same questions but still can not figure out the solution
The error:
The multi-part identifier "Table_2.id" could not be bound.
When I remove the inner join the query runs perfectly fine
I have to solve this problem without turning it into explicit joins because i have so many dynamic filtering which add and x=y clauses to the end of the query
Thank you
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4
LEFT OUTER JOIN (SELECT Count(table_5.offereruserid) AS OfferCount,
table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid) innerQuestion
ON innerQuestion.offereduserspokemonsid = table_2.id
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
If you are keen on keeping the implicit joins, you could split your query into several result sets using WITH. According to this article, you can no longer do "implicit outer joins." Give this a try:
WITH OfferCounts as
(
SELECT Count(table_5.offereruserid) AS OfferCount, table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid
),
EverythingElse AS
(
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4,
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
)
Select *
From EverythingElse t1
left join OfferCounts t2 on t1.offereduserspokemonsid = t2.id
The specific problem comes from the use of implicit joins first and then an explicit join. Lesser lines of code is not a very good reason to use implicit joins, specially since it's deprecated.
Another considerations would be to use table aliases, and also to prefix every column with the corresponding table alias, even if the column is unique between those tables for readability and a code that's easier to maintain.
You are also missing the GROUP BY needed for your aggregation function. All in all, the fixed code would be:
SELECT TOP 10 username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid,
Count(T5.offereruserid) AS OfferCount
FROM Table_1 T1
INNER JOIN Table_2 T2
ON T1.userid = T2.userid
INNER JOIN Table_3 T3
ON T2.pokemonid = T3.pokemonid
INNER JOIN Table_4 T4
ON T2.pokemonid = T4.pokemonid
INNER JOIN Table_5 T5
ON T5.offereduserspokemonsid = T2.id
WHERE pokemonplace = 'trade'
AND T2.userid != 1
GROUP BY username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid;
But, as I said, I suggest that you add the corresponding prefixes to those columns.

sql query for report produce wrong result

I have this problem regarding sql which i will be using in a webservice if I can get this right. What I wanted to do is create a summary report of a transaction. The transaction have header and lines. In a transaction, we are going to input a many planks.
After the inputing, I would like to produce a report that would add all the plank that belongs to a category, then multiply all the planks by the price of that supplier so that I can have the total amount. Here is a pic:
below is my sql which produce wrong output:
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot) as total_board_foot,
su1.price,
sum(t2.board_foot*su1.price) as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2 on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2 on (t1.supplier_id = su2.supplier_id)
left join "supplier_price" su1 on (t2.price = su1.price)
left join "wood_classification" wo1 on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2 on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num,wo1.wood_classification_desc,su1.price,su2.supplier_name,wo2.wood_specie_desc
order by transaction_num,wo2.wood_specie_desc
Evrytime I run that sql, it produces somthing like this:
the transaction that i test only have five planks. 4 planks under Mahogany 6" wider - 7ft. up and 1 Mahogany 5" wider - 7ft. up.
I would guess, that in one of the left joins you have more than one record, which means it give you wrong sum (group by will affect the set after the left join).
Just run the sql without the grouping and check what you get.
So it's probably not the multiplication that causes the problem, it's the sum.
Do you have more than one record in supplier_price with price = 13.33 ? That would be my guess, as all the other joins appear to be on primary keys..
EDIT:
Your problem is that you're joining to supplier_price on the price field, which is not a valid key. Given that your output doesn't take anything from the supplier_price table, I'd be inclined to remove it from the query altogether as below:
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot) as total_board_foot,
t2.price,
sum(t2.board_foot*t2.price) as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2 on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2 on (t1.supplier_id = su2.supplier_id)
left join "wood_classification" wo1 on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2 on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num,wo1.wood_classification_desc,t2.price,su2.supplier_name,wo2.wood_specie_desc
order by transaction_num,wo2.wood_specie_desc
This may solve the issue. But it would help if you provided the relationships between the tables (and the tables' primary keys):
select
t1.transaction_num,
wo1.wood_classification_desc,
wo2.wood_specie_desc,
sum(t2.board_foot)
as total_board_foot,
( SELECT DISTINCT su1.price
FROM "supplier_price" su1
WHERE t2.price = su1.price
) AS price,
sum(t2.board_foot) *
( SELECT DISTINCT su1.price
FROM "supplier_price" su1
WHERE t2.price = su1.price
)
as total_amount
from
"transaction_hdr" t1
left join "transaction_lne" t2
on (t1.transaction_id = t2.transaction_id)
left join "supplier" su2
on (t1.supplier_id = su2.supplier_id)
left join "wood_classification" wo1
on (t2.wood_classification_id = wo1.wood_classification_id)
left join "wood_specie" wo2
on (wo1.wood_specie_id = wo2.wood_specie_id)
group by
t1.transaction_num
, wo1.wood_classification_desc
, su2.supplier_name
, wo2.wood_specie_desc
order by transaction_num
, wo2.wood_specie_desc

SQL - displaying zero results

I am looking to display a 'O' or 'No results found' when no records are found based off my query but can't get it right. I think the problem comes from that I am trying to display information about the records I am counting along with how many there are that fit the criteria. Perhaps its not the count that I need to change with ISNULL but something to modify the result if no rows are outputted.
Thanks for any help in advance.
select t3.countyname, t2.titleunitname, t1.transdesc, count (isnull(t3.orderkey,0)) as c1
from tblorder as t3
left join qryOrderRecord1 as t1 on t3.OrderKey = t1.OrderKey
left join qrytitleunits as t2 on t3.titleunitnum = t2.titleunitnum
WHERE t1.transdesc = 'LETTERS'
AND (t3.OrderDateTime between '7/7/2010' AND '7/7/2010')
AND t3.countyname = 'Frankfurt'
AND t2.titleunitname = 'Maxwell'
group by t3.countyname,t1.transdesc, t2.titleunitname
That count(isnull(column, 0)) is the same as count(1) or count(*). See this question for the why...
Count(*) vs Count(1)
Maybe you want count(t1.orderkey)? This would not count any null t1.orderkey's.
I think you need to count t1.orderkey t3 is on the left side of the outer join so it is the t1.orderkey values that will be NULL.
Also I moved the Filters on t1 and t2 into the JOIN conditions not the WHERE clause
If that doesn't do the trick providing some sample data in your question will help.
SELECT t3.countyname,
t2.titleunitname,
t1.transdesc ,
COUNT(t1.orderkey) AS c1 /*As dotjoe's answer suggests*/
FROM tblorder AS t3
LEFT JOIN qryOrderRecord1 AS t1
ON t3.OrderKey = t1.OrderKey
AND t1.transdesc = 'LETTERS'
LEFT JOIN qrytitleunits AS t2
ON t3.titleunitnum = t2.titleunitnum
AND t2.titleunitname = 'Maxwell'
WHERE t3.OrderDateTime BETWEEN '7/7/2010' AND '7/7/2010' /*Seems odd! Should these be
different dates?*/
AND t3.countyname = 'Frankfurt'
GROUP BY t3.countyname,
t1.transdesc ,
t2.titleunitname
Give this a shot.
select t3.countyname, t2.titleunitname, t1.transdesc, count (isnull(t3.orderkey,0)) as c1
into #Tmp
from tblorder as t3
left join qryOrderRecord1 as t1 on t3.OrderKey = t1.OrderKey
left join qrytitleunits as t2 on t3.titleunitnum = t2.titleunitnum
where t1.transdesc = 'LETTERS'
AND (t3.OrderDateTime between '7/7/2010' AND '7/7/2010')
AND t3.countyname = 'Frankfurt'
AND t2.titleunitname = 'Maxwell'
group by t3.countyname,t1.transdesc, t2.titleunitname
if ##ROWCOUNT > 0
select *
from #Tmp
else
select 'No Results Found.'