Oracle Sql collection columns in where statement - sql

I want to extract data from tableA based on a column stored inside an apex collection:
SELECT c001, c002, c003
FROM apex_collections
WHERE collection_name = 'CollectionA';
Column c001 contains data that I want to map to another table like:
SELECT ID, Name, Country
FROM my_table
WHERE ID = c001;
How can I combine both tables based on an apex collection column?

Using a join, I guess.
select m.id, m.name, m.country
from my_table m join apex_collections c on c.c001 = m.id
where c.collection_name = 'CollectionA';
If you'll use it in PL/SQL, you'll need an INTO clause (as you have to put selected values into something). If you'll use such a query in a cursor FOR loop, then ... well, it depends on what you'll do next.

Related

How can I grab one column from a subquery and insert that column into another table where I can query off of those ID's in another data table?

Trying to explain this the best I can, I have a subquery which is looking for some document information in one table, I need to then use an INSERT INTO to ONLY take the document IDs that are returned and query them in a separate data table.
This is what Im working with right now
use DATABASE
Select * into #Audit
From [dbo].[workflow] A
Where object_id IN
(
Select DISTINCT ChangeHistory.document_id, ChangeHistory.account_number,
min(timestamp)
from [dbo].[xip_workflow] A
INNER JOIN (select B.*
from [dbo].[changehistory] B
where B.doc_status like ('New')
and user_login_name like ('System')
and button_push like (' ')
and B.account_number in ('11111111')
and B.work_queue_system_name in ('r_queue')
and B.document_type in ('A1','A2','A3')
and timestamp > '4/11/2017') ChangeHistory
ON ChangeHistory.[document_id] = A.[object_id]
group by document_id, ChangeHistory.account_number)

query SQL Aggregate rows inside join

Table: ID, Person_ID,Name
Each Person ID can have several rows because he can have several names (first name, last name, nick name, etc..)
I have another table that contains one row per person and some other data in it
I want to join both tables into 1 row per person and in the last column to aggregate all of the person names in to one string like this: "Thomas, anderson, neo"
Something like this:
SELECT A.*,
B.PERSON_ID,
B.(aggregated names here)
FROM USERS A, USERS_NAMES B;
How do i do this?
I would do this in the following way:
select u.*, un.names
from users u left outer join
(select un.person_id, listagg(un.name, ',') within group (order by un.id) as names
from users_names un
group by un.person_id
) un
on u.person_id = un.person_id;
Note that the list aggregation is being done in a subquery. That allows the use of u.* in the outer query with no aggregation. Otherwise, you have to group by each column in users explicitly.

SQL Server - Multiple FROM keywords?

The search term is to ambiguous for google aparently. I am looking at a SQL call and it has 2 FROM keywords? I've never seen this before, can someone explain?
SELECT TOP(5) SUM(column) AS column, column
FROM ( SELECT DISTINCT column, column, column
FROM ((((((table table
INNER JOIN table table ON (column = column
AND column = 2
AND column != '' ))
INNER JOIN table table ON (column = column
AND (column = 144 OR column = 159 OR column = 162 OR column = 164 OR column = 163 OR column = 1 OR column = 2 OR column = 122 OR column = 155 OR column = 156 )))
inner join table table ON (column = column
AND column = 0 ))
INNER JOIN table ON (column = column ))
INNER JOIN table table ON ( column = column
AND (column = 102 OR column = 103 )))
INNER JOIN table table ON (column = column ))) TempTable
GROUP BY column ORDER BY column desc
You will note the multiple FROM keywords. It runs just fine. Just curious to what the purpose is.
This is called as subquery. You can use subquery within your main query
So subquery made the multiple FORM clause.
There's a reason why SQL is called a Structured Query Language: it lets you formulate queries that use other queries as their source, thus creating a hierarchical query structure.
This is a common practice: each FROM keyword is actually paired with its own SELECT, making the inner query a source for the outer one.
Proper formatting would help you understand what is going on: indenting inner SELECTs helps you see the structure of your query, making it easier to understand which part is used as the source of what other parts:
SELECT TOP(5) SUM(price) AS total_price, item_id
FROM ( -- The output of this query serves as input for the outer query
SELECT price, item
FROM order -- This may have its own selects, joins, etc.
GROUP BY order_id
)
GROUP BY item_id
SQL supports SELECTing from the results of another, nested SELECT. As already mentioned, the nested SELECT is called a subquery.
More details about subqueries and examples of their use in MSSQL Server can be found at http://technet.microsoft.com/en-us/library/ms189575(v=sql.105).aspx
Subquery used to select into an aliased column:
USE AdventureWorks2008R2;
GO
SELECT Ord.SalesOrderID, Ord.OrderDate,
(SELECT MAX(OrdDet.UnitPrice)
FROM AdventureWorks.Sales.SalesOrderDetail AS OrdDet
WHERE Ord.SalesOrderID = OrdDet.SalesOrderID) AS MaxUnitPrice
FROM AdventureWorks2008R2.Sales.SalesOrderHeader AS Ord
Using a subquery in the WHERE clause (from http://www.codeproject.com/Articles/200127/SQL-Joins-and-Subqueries)
-- Use a Subquery
SELECT * FROM AdventureWorks.Person.Address
WHERE StateProvinceID IN
(
SELECT StateProvinceID
FROM AdventureWorks.Person.StateProvince
WHERE StateProvinceCode = 'CA'
)
-- Use a Join
SELECT addr.*
FROM AdventureWorks.Person.Address addr
INNER JOIN AdventureWorks.Person.StateProvince state
ON addr.StateProvinceID = state.StateProvinceID
WHERE state.StateProvinceCode = 'CA'
You're seeing FROM clauses in subqueries. If you tabify the query it may be more obvious
SELECT TOP(5) SUM(column) AS column, column
FROM (
SELECT DISTINCT column, column, column
FROM ((((((table table
...
INNER JOIN table table ON (column = column ))) TempTable
GROUP BY column
ORDER BY column desc

Query for missing items in a table

I have a table of airport code pairs:
|iata|icao|
-----------
|ORD |KORD|
|JFK |KJFK|
|LAX |KLAX|
|SFO |KSFO|
I want to run a query that will return the codes that do not exist in this table, so if I run a query (against the iata column) containing ATL,ORD,MIA,SFO it would return ATL and MIA since neither of those exist in my table. Is this possible?
If you have a query that runs code, here is one way:
select mc.*
from (<your query goes here>) mc
where mc.iata not in (select iata from AirportCodePairs acp)
You can also do this with a left outer join and comparison to NULL. I would recommend an index on iata in the pairs table.
Or, if you don't have a query, you can do:
select mc.*
from (select 'ATL' as code union all
select 'ORD' union all
select 'MIA' union all
select 'SFO'
) mc
where mc.iata not in (select iata from AirportCodePairs acp)
You can create a table with the values you are searching for and then do a JOIN:
CREATE TABLE tmp ( code char(3) NOT NULL);
INSERT INTO tmp (code) VALUES ('ATL'), ('ORD'), ('MIA'), ('SFO');
SELECT code FROM tmp
LEFT OUTER JOIN airportcode as ac ON tmp.code = ac.iata
WHERE ac.iata IS NULL
in oracle you could use minus command example
select your_columns from tableA minus select your_columns from tableB
note that both must have same columns and types and lengths or it will not work.
if type is different do cast, to_char, to_date or whatever function is necessary to get types the same. Note if you do have to do one of these or any oracle function call in where clause then use function based indexes. For example, if to_upper is called in where clause like this
select * from tableName a where to_upper(last_name)='SIMPSON'
an index on this would be created as follows
create index ixt on tableName(to_uppper(last_name));

SQL query select and ordering all from same table with key/value pairs

OK, I have a single table with keys and values that I need to query and order from that looks somewhat like this:
Let's say I want to pull all distinct items (resource_no) that are in the webcategory of "dog" (and any other values) and order them by "order" in ascending order so that my result is this:
I can't figure out how to query my table to allow this...I have tried inner joins but they do not seem to work...can anyone help? Thanks!
Kind of tricky to read when it's all in separate rows n the same table, but this should do it for the values you have now. If you're thinking dynamic columns, you'll need to go database specific procedures.
SELECT a.RESOURCE_NO, a.value webcategory, b.value location
FROM resources a
LEFT JOIN resources b ON a.RESOURCE_NO=b.RESOURCE_NO AND b.key='location'
LEFT JOIN resources c ON a.RESOURCE_NO=c.RESOURCE_NO AND c.key='order'
WHERE a.key = 'webcategory' AND a.value='dog'
GROUP BY RESOURCE_NO
ORDER BY c.value
Demo here.
select resource_no
, 'dog'
, location
from YourTable
where webcategory = 'location'
and resource_no in
(
select resource_no
from YourTable
where webcategory = 'dog'
)
order by
location