Issue with insert after subquery - Oracle - sql

I've a sub list of subqueries something like below
WITH QRY1 AS (.. SOME PL SQL STATEMNT),
QRY2 (.. SELECT X,Y,Z,QRY1.* ),
QRY3 (.. SOME SELECT * AGAIN USING QRY2)
and finally
SELECT * FROM QRY3;
is there a way that I can do
INSERT INTO table_name (a,b,c,d)
SELECT * FROM QRY3;

You just need to put the CTE as part of the select, after the insert itself, rather then before it:
INSERT INTO table_name (a,b,c,d)
WITH QRY1 AS (.. SOME PL SQL STATEMNT),
QRY2 (.. SELECT X,Y,Z,QRY1.* ),
QRY3 (.. SOME SELECT * AGAIN USING QRY2)
-- and finally
SELECT * FROM QRY3;
Quick demo:
create table table_name (a number, b number, c number, d number);
insert into table_name (a,b,c,d)
with qry1 as (select 4 as d from dual),
qry2 as (select 2 as b, 3 as c, qry1.* from qry1),
qry3 as (select 1 as a, qry2.* from qry2)
select * from qry3;
1 row inserted.
select * from table_name;
A B C D
---------- ---------- ---------- ----------
1 2 3 4

Related

select 2 recors in case 2 exists

I have 2 rows
code name
1 cake
2 chocolate
This query give me both results
select * from table a where a.code=2 or a.code =1
If one of these records doesn't show, I don't want to retrieve anything.
select * from table a where a.code=2 or a.code =1
and exists ( select 1 from table b where a.code=b.code )
You can use an analytic function:
SELECT code,
name
FROM (
SELECT a.*,
COUNT(DISTINCT code) OVER () AS num_codes
FROM table_name a
WHERE a.code IN (1,2)
)
WHERE num_codes = 2;
Which, for the sample data:
CREATE TABLE table_name (code, name) AS
SELECT 1, 'cake' FROM DUAL UNION ALL
SELECT 2, 'chocolate' FROM DUAL;
Outputs:
CODE
NAME
1
cake
2
chocolate
If you:
DELETE FROM table_name WHERE code = 1;
And run the query again, it outputs:
CODE
NAME
db<>fiddle here
Simple check the count distict
select * from tab1
where code in (1,2)
and (select count(distinct code) from tab1 where code in (1,2)) = 2;
If you want to discard the case where the table has duplicated rows, e.g. 1,1,2
add an other predicate filter
and (select count(*) from tab1 where code in (1,2)) = 2

Can we select count(query) from table

SELECT COUNT(ANOTHER SELECT QUERY) FROM DUAL.
Can we get the results this way or is there any other way?
An example could help:
SQL> create table tabTest as (select 1 x from dual);
Table created.
SQL> select count( select * from tabTest ) from dual;
select count( select * from tabTest ) from dual
*
ERROR at line 1:
ORA-00936: missing expression
SQL> select count(*) from (select * from tabTest);
COUNT(*)
----------
1
You can use a derived table (aka "sub-query")
select count(*)
from (
.... your query here ...
);

ORACLE SQL Query - test a list of keys for NOT EXISTS?

Let's say I have a table with columns K1, K2, V, where (K1,K2) is a composite primary key. I have a list of K1 values 'possiblyNew'. I would like to find all values in that list that have no matches in the table, e.g. (have no idea on proper syntax here)
SELECT PN.K1
FROM [some way of specifying the list inline] as PN
WHERE PN.K1 NOT IN (SELECT T.K1 from myTable T)
This is using Oracle 12. Thanks!
"I have a list of K1 values 'possiblyNew'"
So the question is, where do you have these values? You need to get them into a SQL construct so you can use them in a query.
Let's assume they are numbers, so you can instantiate an array of the collection sys.odcinumberlist with them. Doing this allows you to put them in the FROM clause through the table() function:
SQL> select * from t1;
K1 K2 V
---------- ---------- ---------
1 2 27-JUL-17
2 1 06-JUL-17
4 3 29-JUL-17
SQL> select column_value
2 from table( sys.odcinumberlist ( 2, 3, 4, 5))
3 where column_value not in
4 ( select k1 from t1)
5 /
COLUMN_VALUE
------------
3
5
SQL>
If you have your values on a table, try:
SELECT * FROM TABLE_A WHERE (K1, K2) NOT IN ( SELECT K1, K2 FROM TABLE_B )
If not, you could try one of those:
SELECT * FROM TABLE_A WHERE K1 NOT IN ( 'k1', 'k2', 'k3', ..., 'kn' )
or
WITH myList AS (
SELECT 'k1' AS K
UNION
SELECT 'k2'
)
SELECT * FROM TABLE_A WHERE K1 NOT IN ( SELECT K FROM myList )
or
CREATE TABLE MY_VALUES ( ... )
INSERT INTO MY_VALUES ( 'k2' );
INSERT INTO MY_VALUES ( 'k1' );
...
INSERT INTO MY_VALUES ( 'kn' );
SELECT * FROM TABLE_A WHERE K1 NOT IN ( SELECT K1 FROM MY_VALUES )

Need help identifying dups in the table

What I have:
data_source_1 table
data_source_2 table
data_sources_view view
About tables:
data_source_1:
has no dups:
db=# select count(*) from (select distinct * from data_source_1);
count
--------
543243
(1 row)
db=# select count(*) from (select * from data_source_1);
count
--------
543243
(1 row)
data_source_2:
has no dups:
db=# select count(*) from (select * from data_source_2);
count
-------
5304
(1 row)
db=# select count(*) from (select distinct * from data_source_2);
count
-------
5304
(1 row)
data_sources_view:
has dups:
db=# select count(*) from (select distinct * from data_sources_vie);
count
--------
538714
(1 row)
db=# select count(*) from (select * from data_sources_view);
count
--------
548547
(1 row)
The view is simple as:
CREATE VIEW data_sources_view
AS SELECT *
FROM (
(
SELECT a, b, 'data_source_1' as source
FROM data_source_1
)
UNION ALL
(
SELECT a, b, 'data_source_2' as source
FROM data_source_2
)
);
What I want to know:
How is that possible to have dups in a view where source tables doesn't have dups + 'data_source_x' as source eliminates the possibility of overlapping data.
How to identify dups?
What I've tried:
db# create table t1 as select * from data_sources_view;
SELECT
db=#
db=# create table t2 as select distinct * from data_sources_view;
SELECT
db=# create table t3 as select * from t1 minus select * from t2;
SELECT
db=# select 't1' as table_name, count(*) from t1 UNION ALL
db-# select 't2' as table_name, count(*) from t2 UNION ALL
db-# select 't3' as table_name, count(*) from t3;
table_name | count
------------+--------
t1 | 548547
t3 | 0
t2 | 538714
(3 rows)
Database:
Redshift (PostgreSQL)
The reason is because your data sources have more than two columns. If you do these counts:
select count(*) from (select distinct a, b from data_source_1);
and
select count(*) from (select distinct a, b from data_source_2);
You should find that they are different from the count(*) you get on the same table.
UNION vs UNION ALL
UNION - If the data exist in the TOP Query it's suppressed in the bottom query.
OUTPUT
FOO
UNION ALL - The data repeats as the data exist in both tables (shows both records)
OUTPUT
FOO
FOO

Joining All Rows of Two Tables in SQL Server

My goal is combining all rows in 2 tables. The simplest example I can think of is:
Table 1
Letter
A
B
Table 2
Number
0
1
Combined Table
Letter Number
A 0
B 0
A 1
B 1
I have come up with this SQL statement:
select * from
(
select * From (
select 'A' as 'Letter'
UNION
select 'B' as 'Letter'
) as Letter
) as Letter,
(
select * from (
select 0 as 'Number'
UNION
select 1 as 'Number'
) as Number
) as Number
This works but I don't like it.
defining the same alias multiple times
7 select statements? really....
Does anyone know a cleaner way of doing this? I am sure the answer is out there already but I had no idea how to search for it. Thanks all
Try this
select * from table1 join table2 on 1=1
This is the Cartesian product and if that's what you want to get,
you just have to specify some join condition which is always true.
And try this too.
SELECT * FROM
(
SELECT 'A' AS ch
UNION ALL
SELECT 'B'
)
T1
JOIN
(
SELECT 0 AS dg
UNION ALL
SELECT 1
) T2
ON 1 = 1
In SQL Server you can also do this (if you find it more concise/clear).
SELECT *
FROM
(
VALUES
('A'),
('B')
)
AS ch1(ch)
JOIN
(
SELECT *
FROM
(
VALUES
(0),
(1)
)
AS dg1(dg)
) TBL
ON 1 = 1
Easy enough with CROSS JOIN...
SELECT *
FROM Table1
CROSS JOIN Table2
Result:
Letter Number
------------------------- -----------
A 0
B 0
A 1
B 1
(4 row(s) affected)