SQL Many-to-Many Query in Apex Oracle - sql

I created a many-to-many relationship between the tables PRODUCT_TYPE and LABEL by creating and intermediate table PRODUCT_TYPE-LABELS. I wanted to retrieve all the products that have the labels 'Gluten free' and 'Lactose free' and found help on a similar subject (How to filter SQL results in a has-many-through relation) but never got it to work properly.
The tables are as follows:
PRODUCT_TYPE{
PRODUCT_TYPE ->Primary Key
CONTAINER
VOLUME_L
PRICE_EUROS
...
}
LABEL{
LABEL_NAME ->Primary Key
REQUIREMENTS
}
PRODUCT_TYPE-LABELS{
PRODUCT_TYPE
LABEL_NAME
}
In fact, even when creating the simplest command
SELECT PRODUCT_TYPE-LABELS.PRODUCT_TYPE
FROM PRODUCT_TYPE-LABELS
I obtain the following error ORA-00933: SQL command not properly ended that I can't solve. I'm working on Apex Oracle (Required for this course).
Thanks !

If your table is really named PRODUCT_TYPE-LABELS then you need to enclose it within double quotes. - is not a standard character that is allowed in table names so to use special characters such as that, you need to put quotes around the table. I would recommend AGAINST using a table name such as that and maybe use something like PRODUCT_TYPE_LABEL.
Does the query work from SQL Developer, SQLPlus or any other tool that you can use to run queries?
Try running the query:
SELECT PRODUCT_TYPE
FROM "PRODUCT_TYPE-LABELS"

select * from (
select rownum rowno, CUST_ID,CUST_NAME,no_of_orders,orders_amount,EMAIL from (
select mst.CUST_ID, mst.CUST_NAME, count(mst.INVONO) no_of_orders, sum(SUB_TOTAL) orders_amount, au.EMAIL
from sales_mst mst,CUSTOMER_INFO cust, APP_USERS au
where cust.USER_NAME = au.USERNAME
and cust.cust_id=mst.cust_id
and (au.gender= :P41_GENDER or :P41_GENDER is null)
and (au.DOB = :P41_DOB or :P41_DOB is null)
group by mst.CUST_ID, mst.CUST_NAME,au.EMAIL
having nvl(sum(SUB_TOTAL),0) > 0
order by 3 desc,4 desc
)) where rowno <=:P41_TO_CUSTOMER
/*select * from (
select rownum rowno, CUST_ID,CUST_NAME,no_of_orders,orders_amount from (
select mst.CUST_ID, mst.CUST_NAME, count(mst.INVONO) no_of_orders, sum(SUB_TOTAL) orders_amount
from sales_mst mst
group by mst.CUST_ID, mst.CUST_NAME
having nvl(sum(SUB_TOTAL),0) > 0
order by 3 desc,4 desc
)) where rowno <=:P41_TO_CUSTOMER
*/

Related

Can you force SQL Server to send the WHERE clause to Linked Server?

I'm trying to determine if a table in my SQL Server 2012 database has any records that don't exist in a table that's on a linked Oracle 11g database.
I tried to do this with the following:
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[ORDERS]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511'
The issue is that it never completes because the ORDERS table on the linked server has about 100 million rows and as per the explain plan on SQL Server, it is trying to pull back the entire ORDERS table from the linked server and then apply the WHERE clause.
As per the explain plan, it views the remote table as having an estimated 10000 rows - I assume that's some kind of default if it is unable to get statistics..?
Even running something as simple as this:
select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511'
causes SQL Server to not send the WHERE clause and the query never completes.
I tried to use OPENQUERY however it won't let me add the doc_id to concatenate into the WHERE clause of the query string.
Then I tried to build a select FROM OPENQUERY string in a function but I can't use sp_executesql in a function to run it.
Any help is greatly appreciated.
I think this would logically work for you, but it may take too long as well.
SELECT sql_ord.*
FROM my_order_table sql_ord
LEFT JOIN LINK_ORA..[SCHEMA1].[ORDERS] ora_ord ON sql_ord.document_id = ora_ord.doc_id
WHERE sql_ord.document_id = 'N2324JKL3511'
AND ora_ord.doc_id IS NULL
Since you have problem with something as simple as select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511' have you try to create a table on the remote server that will hold the doc_id that you want to look at. So your SELECT will include a table that contain only 1 row. I'm just not sure about the INSERT since I can't test it for now. I'm assuming that everything will be done on the remote server.
So something like :
CREATE TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id (
doc_id nvarchar(12));
INSERT INTO LINK_ORA..[SCHEMA1].linked_server_doc_id (doc_id)
SELECT doc_id
FROM LINK_ORA..[SCHEMA1].[ORDERS] WHERE doc_id = 'N2324JKL3511';
select 1
from my_order_table ord
where not exists (select 1
from LINK_ORA..[SCHEMA1].[linked_server_doc_id]
where doc_id = ord.document_id)
and document_id = 'N2324JKL3511';
DROP TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id

selecting minimum value depending on other value

Is there any better way for below sql query? Don't want to drop and create temporary table just would like to do it in 1 query.
I am trying to select minimum value for price depending if its order sell where obviously price is higher then in buy and it just shows 0 results when I try it.
DROP TABLE `#temporary_table`;
CREATE TABLE `#temporary_table` (ID int(11),region int(11),nazwa varchar(100),price float,isBuyOrder int,volumeRemain int,locationID int,locationName varchar(100),systemID int,security_status decimal(1,1));
INSERT INTO `#temporary_table` SELECT * FROM hauling WHERE isBuyOrder=0 ORDER BY ID;
SELECT * FROM `#temporary_table`;
SELECT * FROM `#temporary_table` WHERE (ID,price) IN (select ID, MIN(price) from `#temporary_table` group by ID) order by `ID`
UPDATE: when I try nvogel answer and checked profiling thats what I get:
Any chance to optimize this or different working way with 700k rows database?
Try this:
SELECT *
FROM hauling AS h
WHERE isBuyOrder = 0
AND price =
(SELECT MIN(t.price)
FROM hauling AS t
WHERE t.isBuyOrder = 0
AND t.ID = h.ID);
You don't need a temporary table at all. You can basically use your current logic:
SELECT h.*
FROM hauling h
WHERE h.isBuyOrder = 0 AND
(h.id, h.price) IN (SELECT h2.id, MIN(h2.price)
FROM hauling h2
WHERE h2.isBuyOrder = 0
)
ORDER BY h.id
There are many other ways to write similar logic. However, there is no need to rewrite the logic; you just need to include the comparison on isBuyOrder in the subquery.
Note that not all databases support IN with tuples. If your database does not provide such support, then you would need to rewrite the logic.

Table Aliases into Subqueries

(Submitting here to assist other Snowflake Users who may run into similar challenges... Interested to see if there are any additional recommendations beyond what's bee provided already.)
Why doesn't table alias work into subqueries?
I was using a sample table select query but it doesn't work when I coded a table alias.
select * from SNOWFLAKE_SAMPLE_DATA.TPCDS_SF100TCL.STORE as t
where
t.S_REC_START_DATE = (
select max(i.S_REC_START_DATE) from t as i
where i.S_REC_START_DATE < '2000-01-01'
)
I got a SQL compilation error: Object 'T' does not exist.
is not possible to use table alias?
(Previously provided by Mike Walton, a tenured member of Snowflake's Professional Services team)
You can, but not that way. You should use a CTE, instead:
WITH t as (
select * from SNOWFLAKE_SAMPLE_DATA.TPCDS_SF100TCL.STORE
)
select * FROM t
where t.S_REC_START_DATE = (
select max(S_REC_START_DATE) as S_REC_START_DATE from t
where S_REC_START_DATE < '2000-01-01'
)
Any other ideas and/or recommendations?

RODBC, SQL Order By clause + field ID = Order conflict

Does this make sense? I otherwise don't see the error.
Using RODBC, R returns a 'Could not SQLExecDirect' error for a sqlQuery statement issued to a table containing a field ID = Order. The SQL otherwise works. I can however read the entire table to a df using sqlFetch (see below).
The target db is on SQL Server.
Example of table structure:
Taxon_Id = c(3000,3001,3002)
Group_Id = c(6,5,5)
Type = c('Fish','Fish','Fish')
Order = c('Petromyzontidae','Acipenseridae','Clupeidae')
Family = c('Petromyzontidae','Acipenseridae','Clupeidae')
txn = data.frame(Taxon_Id,Group_Id,Type,Order,Family)
Example of SQL issued to table:
txn2<-as.data.frame(sqlQuery(channel, paste('SELECT T.Taxon_Id,
T.GroupId,
T.Type,
T.Order,
T.Family
FROM Taxon T
ORDER BY 1
')) )
sqlFetch reads all table fields without error.
txn<-as.data.frame(sqlFetch(channel,"Taxon"))
Thanks for your comments.
This is your query:
SELECT T.Taxon_Id, T.GroupId, T.Type, T.Order, T.Family
FROM Taxon T
ORDER BY 1
In SQL (in general) and SQL Server (in particular), the word Order is a reserved word. You need to escape it with either double quotes or square braces:
SELECT T.Taxon_Id, T.GroupId, T.Type, T.[Order], T.Family
FROM Taxon T
ORDER BY 1

Need help with error in Oracle SQL query

this is the query:
SELECT DISTINCT pprom.pk
FROM
(
SELECT
item_t0.SourcePK as pk
FROM
links item_t0
WHERE (? = item_t0.TargetPK AND item_t0.SourcePK in (?,?))
AND (item_t0.TypePkString=? )
UNION
SELECT
item_t1.TargetPK as pk
FROM
cat2prodrel item_t1
WHERE ( item_t1.SourcePK in (? ) AND item_t1.TargetPK in (?,?))
AND (item_t1.TypePkString=? )
) AS pprom
And this is the error:
ORA-00933: SQL command not properly ended
Any ideas what could be wrong?
Edit:
The question marks are replaced by PKs of the respective items:
values = [PropertyValue:8802745684882, PropertyValue:8796177006593, PropertyValue:8796201713665, 8796110520402, PropertyValue:8796125954190, PropertyValue:8796177006593, PropertyValue:8796201713665, 8796101705810]
Edit 2:
The query is executed deep inside some proprietary software system so I don't know exactly the code that runs it.
Edit 3:
I found one more query that's a little shorter but results in the same error message:
SELECT DISTINCT pprom.pk
FROM
(
SELECT
item_t0.SourcePK as pk
FROM
links item_t0
WHERE (? = item_t0.TargetPK AND item_t0.SourcePK in (?))
AND (item_t0.TypePkString=? )
) AS pprom
Using the following values:
values = [PropertyValue:8799960601490, PropertyValue:8796177006593, 8796110520402]
Edit 4
I found the SQL code that is sent to the db after replacing the values:
SELECT DISTINCT pprom.pk
FROM
(
SELECT
item_t0.SourcePK as pk
FROM
links item_t0
WHERE (8801631769490 = item_t0.TargetPK AND item_t0.SourcePK in (8796177006593))
AND (item_t0.TypePkString=8796110520402 )
) AS pprom
I also tried executing the inner SELECT statement and that alone runs ok and returns a single PK as a result.
I could not find any obvious syntax error in your query so I'd presume the issue is the client library you are using to convert the ? place holders into actual values. Your question edit displays a sort of dump where there are 8 integers but only 6 PropertyValue items. Make sure that's not the issue: IN (?, ?) requires 2 parameters.
Edit
Try removing the AS keyword when you assign an alias to the subquery:
SELECT DISTINCT pprom.pk
FROM
(
SELECT
item_t0.SourcePK as pk
FROM
links item_t0
WHERE (8801631769490 = item_t0.TargetPK AND item_t0.SourcePK in (8796177006593))
AND (item_t0.TypePkString=8796110520402 )
) AS pprom
^^