Oracle DB Just Combine Two tables Side By Side - sql

1:Table COUNTRY
ID NAME
1 USA
2 BRITAIN
2:Table PEOPLE
P_ID P_NAME
4 JOHN
5 MONTY
Resultant table should have
ID NAME P_ID P_NAME
1 USA 4 JOHN
2 BRITAIN 5 MONTY
Just side by side merge. Is it possible? LIKE TABLE1 | TABLE2

Example
with x as (
select id, name, rownum rn from country
order by id),
y as(
select p_id, p_name, rownum rn from people
order by p_id)
select id,name,p_id,p_name from x
left join y on y.rn = x.rn
union
select id,name,p_id,p_name from y
left join x on y.rn = x.rn

If I well understood your question this could work:
SELECT *
FROM (SELECT T1.*,ROWNUM AS R FROM COUNTRY T1) V1,
(SELECT T2.*,ROWNUM AS R FROM PEOPLE T2) V2
WHERE V1.R = V2.R(+)
But you need to know wich table is bigger and I fear you aren't going to to get reliable results

This should work..
select c.id,c.name, p.p_id, p.p_name from country c inner join people p on c.id = p.p_id;

Try this:
SELECT * FROM COUNTRY C
INNER JOIN PEOPLE P ON C.ID = P.P_ID;
Updated answer :
Select * from #country as c , #people as p where p_id =4 and id=1 OR id = 2 and p_id=5

Related

SQL Server: how to limit results based on query

I have a customer table, and a customer address table but I want to limit it by just one address. so even though a customer has two postal addresses I want to show only one for each customer. Forgive me if this is a silly question, I am new to programming
custid forename surname
---------------------------
1 Sam Supra
2 Kelly Kenwood
addid custid address addresstype
-------------------------------------------
1 1 Main street POSTAL
2 1 2nd Main street POSTAL
3 1 0712456254 Mobile
4 1 0526545686 LANDLINE
5 2 Second Street POSTAL
6 2 04756325654 Mobile
7 2 058654236545 LANDLINE
Query:
SELECT a.*
FROM dbo.customers a
LEFT OUTER JOIN dbo.addresses b ON a.custid = b.custid
WHERE b.addresstype = 'POSTAL'
You can use ROW_NUMBER():
SELECT c.*, a.*
FROM dbo.customers c LEFT JOIN
(SELECT a.*,
ROW_NUMBER() OVER (PARTITION BY a.custid ORDER BY a.addid DESC) as seqnum
FROM dbo.addresses a
WHERE a.addresstype = 'POSTAL'
) a
ON a.custid = c.custid AND seqnum = 1;
Notes:
Don't use arbitrary table aliases. Use abbreviations for the table names.
Presumably, you want to select the addresses, so I changed the SELECT clause.
This returns all customers, even those with no address. I am guessing that is your intention, although your query would return only customers with a postal address.
I assume you are interested in the last address entered:
SELECT
*
FROM
dbo.customers a
LEFT JOIN
dbo.addresses b on b.id =
(
SELECT
x.id
FROM
dbo.addresses x
WHERE
x.custid = a.custid
AND
x.addresstype = 'POSTAL'
ORDER BY
x.id DESC
)
SELECT c.*,
a.*
FROM dbo.customers c
LEFT JOIN (
SELECT a.*,
ROW_NUMBER() OVER (
PARTITION BY a.custid
ORDER BY a.addid DESC
) as seqnum
FROM dbo.addresses a
WHERE a.addresstype = 'POSTAL'
) a
ON a.custid = c.custid AND seqnum = 1;

SQL query to find a record which has all matching records in another table

I have below 3 tables and I want to write a SQL query which will list the store present in all city: (here the result should be "Walmart")
Stores:
ID Name
1 Walmart
2 Target
3 Sears
Stores_City
ID Store_id City ID
1 1 10
2 1 20
3 2 10
4 1 30
City
ID Name
10 NewYork
20 Boston
30 Eagan
I am unable to find a query that works. Any help is appreciated!
select s.Name
from Stores s
inner join
(
select store_id, count(distinct city_id)
from stores_city
group by store_id
having count(distinct city_id) = (select count(*) from City)
) x
on x.store_id = s.id;
You can do it by grouping on store_id and checking for the count from stores table.
A straight join would work
Select distinct s.name from stores s inner join store _city SC on s.id=sc.id
Inner join city c on
Sc.city_id = c.id
Here is another way that will work:
select s.*
from stores s
where not exists (
select c.id
from city c
except
select sc.city_id
from stores_city sc
where sc.store_id = s.id
)
Try this:
SELECT
s.Name
FROM Stores s
WHERE NOT EXISTS (SELECT TOP 1
1
FROM City c
LEFT JOIN Stores_City sc
ON c.ID = sc.CityID
AND sc.Store_id = s.ID
WHERE sc.ID IS NULL)

SQL Server - For each distinct company count the number of employees

I am trying to create some SQL that will count the number of employees within each company and return only those companies with greater than or equal to n employees.
I have the following tables (simplified):
CompanyEmployee Table
ID Name IsCompany
1 John Joe 0
2 Company Y 1
3 Company X 1
4 Sally Jeff 0
5 James Peach 0
Employment Table
ID EmployeeID CompanyID
1 1 2
2 4 3
3 5 3
My desired result for n=2:
ID Name IsCompany
3 Company X 1
I have the following SQL:
SELECT t.* FROM CompanyEmployee AS t
WHERE t.ID IN (
SELECT DISTINCT (t.ID)
FROM CompanyEmployee AS t
INNER JOIN Employment AS t0 ON t.ID = t0.CompanyID
WHERE t.IsCompany = 1
GROUP BY t0.CompanyID
HAVING COUNT(t0.EmployeeID) >= n)
But it generates the following error:
Column 'CompanyEmployee.ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Any help or advice would be greatly appreciated!
Mixing companies and employees this way is a bad idea. Using a straight inner join may work as long as the id values between the two different types of rows never intersect. I guess if it's an identity column then that's not supposed to happen.
with Companies as (
select ID as CompanyID, Name
from CompanyEmployee
where IsCompany = 1
), Employees as (
select CompanyID, Name
from CompanyEmployee where
IsCompany = 0
)
select c.CompanyID, Name, 1 as IsCompany
from
Companies as c
inner join Employment as ec on ec.CompanyID = c.CompanyID
inner join Employees as e on e.EmployeeID = ce.EmployeeID
group by
c.CompanyID
having count(*) >= n
There is still a straightforward way to do it:
select *
from CompanyEmployee
where ID in (
select CompanyID
from Employment
group by CompanyID
having count(*) >= n)
)
Try this:
SELECT t1.CompanyId, t2.CompanyName, COUNT(t1.CompanyId)
FROM Employment AS t1 INNER JOIN CompanyEmployee AS t2 ON t1.CompanyId = t2.Id
GROUP BY t1.CompanyId, t2.CompanyName
HAVING COUNT(t1.CompanyId)>=n
where n is a number of employees...

SQL First row only following aggregation Rules

I need to select only the most significant value from a table. Using Postgre SQL (last version) Follows the data sample:
Table Company
Id, Name, ExternalId, StartAt
1 Comp1 54123 21/05/2000
2 Comp2 23123 21/05/2000
Table Address
Id, Company, Address_Type, City
1 1 7 A
2 2 2 B
3 2 62 C
Table Adress_Type
Id, Name, importance_order
62 Adt1 1
7 Adt2 2
2 Adt3 2
What i need to do is to get the company and its major Address, based on the "importance_order". There is already a function that returns this result:
Create function~~~~
Select * from Company c
join Address a on c.address_id = a.id
Join AddressType at on a.adresstype_id = at.id
ORDER by at.importance_order
Limit 1
My problem now is that this function is called one time for every row in the query, and it take so much time (about 20 min.). Should it be possible to do this similar aproach by joinning tables? I need this join to get the First "most important"address, and then get the City name, but need to do this in a "faster" way. I need to reduce subquery`s number to its minimal.
Select * from table t
inner join Company c on t.company_id = c.id
left join address a on (c.company_id = c.id)
left join addresstype at on (a.adresstype_id = at.id)
where at.id = (
select max(id) from addresstype
where adresstype in (
select adresstype from adress where company_id = c.id
)
)
If it is not clear tell me that i get more into details.
Thanks.
For this you need PostgreSQL 8.4+ I suppose
SELECT T.*
FROM TABLE AS T
INNER JOIN
(
SELECT * FROM
(
SELECT C1.*, ROW_NUMBER() OVER(partition by C1.ID ORDER BY T.IMPORTANCE_ORDER) AS RN
FROM COMPANY AS C1
INNER JOIN ADDRESS AS A
ON C1.ID = A.COMPANY
INNER JOIN ADDRESS_TYPE AS T
ON T.ID = A.ADDRESS_TYPE_ID
) A
WHERE RN = 1
) AS B
ON B.ID= T.COMPANY_ID

Sql get MAX for other value

I would like to figure out how to select a table where the value is the ID of the person with the highest pay.
So if I had
Table=theJobs
JobID Pay
----------
12345 10
12346 12
12347 13
table=thePerson
Person JobID
--------------
Person1 1
Person2 2
Person3 3
table=hire(FKs)
JobID PersonID
----------------
12345 2
12347 1
12346 3
I'd like it to show the max payed person so it should show
Person1
I tried to use where for the a Max function but it seems to fail. I'm pretty sucky at these group functions. I guess I'm more asking how to use a group function as a constraint than anything. Since I had a similar issue a bit ago.
This solution will work in pretty much any database system:
Select ....
From thePerson As P
Join (
Select H1.PersonId, Max( J1.Pay ) As MaxPay
From hire As H1
Join theJobs As J1
On J1.JobId = H1.JobID
Group By H1.PersonId
) As PayPerPerson
On PayPerPerson.PersonId = P.Person
Where Exists (
Select 1
From hire As H2
Join theJobs As J2
On J2.JobId = H2.JobID
Where H2.PersonId = P.Person
Having Max( J2.Pay ) = PayPerPerson.MaxPay
)
If you are using a DBMS that supports ranking functions and common-table expressions such as SQL Server 2005 and later, then the problem is easier. This solution will show only one name and ignore ties:
With RankedPay As
(
Select ...
, Row_Number() Over( Order By J.Pay Desc ) As Rnk
From thePerson As P
Join hire As H
On H.PersonId = P.Person
Join theJobs As J
On J.JobId = H.JobId
)
Select ...
From RankedPay
Where Rnk = 1
This solution will show any that match the top pay and include ties:
With RankedPay As
(
Select ...
, Rank() Over( Order By J.Pay Desc ) As Rnk
From thePerson As P
Join hire As H
On H.PersonId = P.Person
Join theJobs As J
On J.JobId = H.JobId
)
Select ...
From RankedPay
Where Rnk = 1
SELECT p.Person
FROM person p JOIN hire h ON p.PersonID = h.PersonID
JOIN theJobs j ON h.JobID = j.JobID
ORDER BY j.Pay DESC
LIMIT 1;
If you are using a RDBMS that does not support the LIMIT clause, try using the TOP clause instead:
SELECT TOP 1 p.Person
FROM person p JOIN hire h ON p.PersonID = h.PersonID
JOIN theJobs j ON h.JobID = j.JobID
ORDER BY j.Pay DESC