Selecting multiple ID's from a table gives error ORA-02070 - sql

When I try to select multiple ID's from a table, I am getting error ORA-02070.
Here is the query that I am using:
select *
from hrs_employee_store
where employee_id in (13511677, 576000);
Here is the error which I am getting:
ORA-02070: database ODS_XSTORE does not support TO_NUMBER in this context
Also, when I use this query,
select * from hrs_employee_store
where employee_id in ('13511677', '576000');
I am just getting the row for 13511677.
Is there a way to fix this issue? Thanks

I suspect that EMPLOYEE_ID is not a number. Try:
select *
from hrs_employee_store
where EMPLOYEE_ID in ('13511677', '576000');
This returns matching employees, meaning there is no match for the second.
If you want NULL values for all the extra columns, you can use left join:
select *
from (select '13511677' as employee_id from dual union all
select '576000'
) eid left join
hrs_employee_store es
using (employee_id);

Related

SQL if statement to select items form different tables

I am creating a new table joining 3 different tables. The problem is that I have some data that I want to select for other_info divided into two different tables. table_1 has preference over table_2, but it is possible that in table_1 are missing values. So, I want to select the value of box if it's not empty from table_1 and select it from table_2 if the value in table_1 does not exist.
This is the code I have very simplified, but I think it's enough to see what I want to do. I've written an IF ... ELSE statement inside a with, and this is the error I get:
Syntax error: Expected "(" or keyword SELECT or keyword WITH but got keyword IF at [26:5]
Besides, I've tried different things inside the conditional of the if, but none of them is what I expect. Here is the code:
CREATE OR REPLACE TABLE `new_table`
PARTITION BY
Current_date
AS (
WITH info AS (
SELECT
Date AS Day,
Box,
FROM
`table_1`
),
other_info AS (
IF (...)
BEGIN{
SELECT
Date AS Day,
Box
FROM
`table_1`}
END
ELSE
BEGIN{
SELECT
Date AS Day,
Box
FROM
`table_2`}
END
)
SELECT
Date
Box
Box_description
FROM
`table_3`
LEFT JOIN info(Day)
LEFT JOIN other_info(Day)
)
You're not going to be able to embed an IF within a CTE or a Create-Table-As.
An alternative structure can be to union two queries with mutually exclusive WHERE clauses... (Such that only one of the two queries ever returns anything.)
For example, if the code below, something is checked for being NULL or NOT NULL, and so only one of the two can ever return data.
WITH
info AS
(
SELECT
Date AS Day,
Box,
FROM
`table_1`
),
other_info AS
(
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
THIS BIT
--------------------------------------------------------------------------------
SELECT
Date AS Day,
Box
FROM
`table_1`
WHERE
(SELECT MAX(x) FROM y) IS NULL
UNION ALL
SELECT
Date AS Day,
Box
FROM
`table_2`
WHERE
(SELECT MAX(x) FROM y) IS NOT NULL
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
)
SELECT
Date
Box
Box_description
FROM
`table_3`
LEFT JOIN info(Day)
LEFT JOIN other_info(Day)
In stead of the if..., you could do something like this (in MySQL):
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2 WHERE `date` NOT IN (SELECT `date` FROM table1)
I am not sure (as in: I did not test), but I do think this is also possible in google-bigquery
see: DBFIDDLE

In clause of a select but with more than one value to look for

I have a set of results that I query with connect by prior, now I need to check in the where clause of a query if ONE of those results is IN some other set of values(a select * from another table). I'm trying to use 'IN' but I think that that only works when I have one unique value to check for, and not a group of values.
SELECT COUNT('X')
INTO V_COUNT
FROM SIC_NEA_CATFRU
WHERE (SELECT cod_nivel_estr_art
FROM niveles_estr_art
CONNECT BY PRIOR cod_nivel_estr_art_P = cod_nivel_estr_art
START WITH cod_nivel_estr_art = V_COD_NIVEL_eSTR_ART) IN ( SELECT COD_NIVEL_eSTR_ART FROM SIC_NEA_CATFRU);
Would the intersect set operator do? Something like this: first query is your hierarchical query, while the second returns values from the sic_nea_catfru table. If there are any matches, you'll know how many:
SELECT COUNT (*)
INTO v_count
FROM ( SELECT cod_nivel_estr_art
FROM niveles_estr_art
CONNECT BY PRIOR cod_nivel_estr_art_p = cod_nivel_estr_art
START WITH cod_nivel_estr_art = v_cod_nivel_estr_art
INTERSECT
SELECT cod_nivel_estr_art FROM sic_nea_catfru)

"NOT IN" SQL across 2 oracle databases

I have 2 Oracle databases A & B. I connect to A and run following SQLs:
SELECT * FROM employee has 2000 rows.
SELECT empId FROM B.xx has 700 rows.
SELECT * FROM employee ​WHERE empId IN (SELECT empId FROM B.xx) has 698 rows.
SELECT * FROM employee WHERE empId NOT IN (SELECT empId FROM B.xx) return nothing!!!
I don't know why the last SQL didn't return anything. Is it because of "cross database"?
I can't re-produce this if I replace B.xx to another table in A.
The most probable reason is that empId has NULL values in the table B.xx.
Try to run
SELECT * FROM employee WHERE empId NOT IN (SELECT empId FROM B.xx where empId is not NULL)
this will give you a valid count.
That's just how not in works.
NOT IN does not behave as expected if any of the results returned by the subquery are NULL. As you observe, it returns no rows at all.
For this reason, I strongly recommend always using NOT EXISTS:
SELECT e.*
FROM employee e
WHERE NOT EXISTS (SELECT 1 FROM B.xx x WHERE x.empId = e.empId);
Although you can fix the problem by adding a WHERE x.empId IS NOT NULL, I think that is a dangerous habit. Sometime you are likely to leave out the WHERE clause and mistakenly think that there are no mismatches (yes, this has happened to me). This cannot happen if you always use NOT EXISTS.

Cross join InterBase get duplicate record based on condition

I am working with InterBase at the moment by Using Firebird. I need to get a record twice with a condition, but every time I run the query I keep getting an error message. Is there a way to get around the cross join in InterBase? Will there be a simpler way to get around to add this logic to the query. It seems like Firebird wont accept the cross join.
SELECT EMPLOYEE_NAME, LAST_NAME, CACODE
FROM EMPLOYEESTABLE
(
SELECT 889 AS CACODE, 8592-265-44444 AS STANDARDCACODE
UNION ALL
SELECT 695 AS CACODE, 8554-265-44578 AS STANDARDCACODE
) C
Select always needs from. The table RDB$DATABASE returns 1 row with the database name so we can use that. I think you are looking to do this:
SELECT EMPLOYEE_NAME, LAST_NAME, CACODE
FROM EMPLOYEESTABLE,
(
SELECT 889 AS CACODE, '8592-265-44444' AS STANDARDCACODE FROM RDB$DATABASE
UNION ALL
SELECT 695 AS CACODE, '8554-265-44578' AS STANDARDCACODE FROM RDB$DATABASE
) C
SELECT
889 AS CACODE,
/* '8592-265-44444' AS STANDARDCACODE, >>unused<< */
EMPLOYEE_NAME,
LAST_NAME
FROM EMPLOYEESTABLE
UNION ALL
SELECT
695 AS CACODE,
/* '8554-265-44578' AS STANDARDCACODE, >>unused<< */
EMPLOYEE_NAME,
LAST_NAME
FROM EMPLOYEESTABLE
Who need joins with such a simple query :-D

SQL Server CTE use IDs from single column with EXCEPT?

Having received kindness the other day from someone whose eyes were less bleary than mine I thought I'd give it another shot. Thanks in advance for your assistance.
I have a single SQL Server (2012) table named Contacts. That table has four columns I am currently concerned with. The table has a total of 71,454 rows. There are two types of records in the table; Companies and Employees. Both use the same column, named (Client ID), for their primary key. The existence of a Company Name is what differentiates between Company and Employee data. Employees have no associated Company Name. There are 29,021 Companies leaving 42,433 Employees.
There may be 0-n number of Employees associated with any one Company. I am attempting to create output that will reflect the relationship between Companies and Clients, if there are any. I would like to use the Company ID (Client ID column) as my anchor data set.
Not sure my definition is correct but the thought was to create a CTE of the known Companies by virtue of a given Company Name. Then, use the remaining Client IDs but use the EXCEPT clause to filter the already-retrieved Client IDs out of the result set.
Here the code I currently have;
;
WITH cte ( BaseID, Client_id, Company_name,
First_name, Last_name, [level] )
AS ( SELECT Client_id AS BaseID ,
Client_id ,
Company_name ,
First_name ,
Last_name ,
1
FROM dbo.Conv_client_clean
WHERE ( COMPANY_NAME IS NOT NULL
OR COMPANY_NAME != ''
)
UNION ALL
SELECT c.BaseID ,
children.Client_id ,
children.Company_name ,
children.First_name ,
children.Last_name ,
cte.[level] + 1
FROM dbo.Conv_client_clean children
INNER JOIN cte c ON c.Client_id = children.CLIENT_ID
EXCEPT
SELECT children.Client_id
FROM cte
)
SELECT BaseID ,
Client_id ,
Company_name ,
first_name ,
Last_name ,
[Level]
FROM cte
OPTION ( MAXRECURSION 0 );
In this instance I receive the following error;
Msg 252, Level 16, State 1, Line 3
Recursive common table expression 'cte' does not contain a top-level UNION ALL operator.
Any suggestions?
Thanks!
In the recursion cte query, you cannot have more set operations(union, except, union all,intersect) after the the one Union ALL which is refers the cte itself. I think what you can try is change the query as below and check
...
UNION ALL
SELECT c.BaseID ,
children.Client_id ,
children.Company_name ,
children.First_name ,
children.Last_name ,
cte.[level] + 1
FROM dbo.Conv_client_clean children
WHERE children.Client_id NOT IN (SELECT Client_id FROM cte)
As mentioned to Kiran I was able to concoct an 'old fashioned' approach what is good enough for now.
Thank you everyone for your kind attention.
I'm not sure what you are trying to do with level. It seems that it will be 1 for companies and 2 for employees. If that's the case, you don't even need recursion. The first part of your cte creates a list of companies. That's fine. Now use that to join back to the original table to show all the employees too.
WITH
cte( BaseID, ClientID, Company_name, First_name, Last_name )AS(
SELECT Base_ID,
Base_ID AS Client_id ,
Company_name,
First_name,
Last_name
FROM dbo.Conv_client_clean
WHERE COMPANY_NAME IS NOT NULL
OR COMPANY_NAME <> ''
)
select c2.Base_id, c2.Client_id,
c1.Company_Name, c2.First_Name, c2.Last_Name,
case when c2.client_id is null then 1 else 2 end Level
from cte c1
join Conv_client_clean c2
on c1.BaseID = isnull( c2.Client_ID, c2.Base_id )
order by c1.BaseID, c2.Base_id;
Here's where I fiddled with it.
Unfortunately anything besides UNION ALL, after you've made your recursive reference, will not work. And if you think about it, it makes sense.
Recursion is conceptually identical to the following where recursion continues until max depth is reached or a query returns no results upon which another execution could act.
WITH Anchor AS (select...)
,recurse1 as (<Some body referring to Anchor>)
,recurse2 as (<Identical body except referring to recurse1>)
,recurse3 as (<Identical body except referring to recurse2>)
...
select * from Anchor
union all
select * from recurse1
union all
select * from recurse2
...
The problem is that conjunctive operators apply to EVERYTHING that precedes it. In your case, EXCEPT operates on everything to it's left side which includes the Anchor query. Afterwards, when looking for the anchor to which the recursive part must be applied, the query compiler doesn't find a 'top level union all operator' any more because it's been consumed as part of the left side of your recursive query.
It wouldn't help to contrive some syntax akin to parenthesis that could delimit the scope of the left side of your table conjunction because you would then build a case of 'multiple recursive references' which is also illegal.
BOTTOM LINE IS: The only conjunction that works in the recursive part of your query is UNION ALL because it simply concatenates the right side. It doesn't require knowledge of the left side to determine which rows to include.