SELECT with multiple PRIMARY KEY - sql

I have 3 table:
nation (name PRIMARY KEY);
city (name PRIMARY KEY, nation REFERENCES nation(name))
overflight (number, city, PRIMARY KEY (number, city))
The overflight table content is something like below:
AA11 city1
AA11 city2
BB22 city1
BB22 city3
etc.
I need to select only overflight that doesn't have city from a certain nation in the city field.
I've tried with:
SELECT number
FROM overflight
JOIN city ON overflight.city = city.name
WHERE overflight.city NOT IN (
SELECT name FROM city WHERE nation = some_nation
)
GROUP BY number;
but it doesn't work because it doesn't list the row of overflight that have city from some_nation but can happen that the same overflight have another row in the table that doesn't have city in some_nation. How can I display only the overflight that doesn't have city in some_nation at all?
Hope that I've explained my problem as clear as possible.
EDIT
This is exact content of overflight table:
AZ 7255 Rome
AZ 7255 Milan
AZ 608 Rome
AZ 608 New York
AA 1 New York
AA 1 Los Angeles
BA 2430 New York
BA 2430 Los Angeles
Suppose that I want to show the overflight that doesn't fly over any city in Italy. I need that the result is like this
AA 1 New York
AA 1 Los Angeles
BB 2430 New York
BB 2430 Los Angeles

Join the tables to get the overflight numbers that do have a city from the nation that you want to exclude and use the operator NOT IN to select all the other oveflights:
SELECT * FROM overflight
WHERE number NOT IN (
SELECT o.number
FROM overflight o INNER JOIN city c
ON o.city = c.name
WHERE c.nation = 'Italy'
)
See the demo.
Results:
number
city
AA 1
New York
AA 1
Los Angeles
BA 2430
New York
BA 2430
Los Angeles

Related

How to show blank when value is repeated

SELECT * FROM Cities ORDER BY Country;
This is the result.
COUNTRY CITY PLACE
Italy Milan Zone_A
Italy Rome Zone_A
Italy Rome Zone_B
USA New York Zone_Q
USA Atlanta Zone_A
I would like to create a Stored Procedure that shows "blank" when the item is repeated. The final result should be the following. (Note that this rule is applied only in the first 2 columns, not in the third).
COUNTRY CITY PLACE
Italy Milan Zone_A
Rome Zone_A
Zone_B
USA New York Zone_Q
Atlanta Zone_A
If your version of maria DB supports window functions, you can use lag():
select
case when lag(country) over(order by country, city, place) = country
then null
else country
end country,
case when lag(city) over(order by country, city, place) = city
then null
else city
end city,
place
from cities
order by
country,
city,
place

subquery with NOT IN

I have a table of cities like:
state city
----- ----
texas houston
texas austin
texas dallas
texas san antonio
texas beaumont
texas brownsville
texas el paso
california anaheim
california san diego
california los angeles
california oakland
california simi valley
california san francisco
I need a query to find the states that don't have a city named 'houston' or 'dallas'. My first thought was this
select distinct state from cities where city not in ('houston', 'dallas');
but that won't work. I think I need a subquery and a NOT IN of some sort..
A way you can do this is with a NOT EXISTS clause:
Select Distinct State
From Cities C1
Where Not Exists
(
Select *
From Cities C2
Where C2.City In ('Houston', 'Dallas')
And C1.State = C2.State
)
select distinct state from cities where state not in (SELECT state FROM cities WHERE city in ('houston', 'dallas'));
Another method, may be slightly faster:
select distinct state from cities where state not in (select state from cities where city in ('houston', 'dallas'));
Select State
from Cities
group by State
having count(case when Cities in ('houston', 'dallas') then cities end) = 0
This will return all states where the number of cities associated with that state and matching your criteria is 0 (i.e. there are no such cities associated with the state).

How to do Conditional Column Joins in SQL?

I have a tables below
Main Table: tblMain
Phase Country City
AAA India Bangalore
AAA USA Chicago
ZZZ USA
ZZZ UK
SubTable: tblSub
Phase Country City Value
AAA USA Chicago 3
AAA USA NY 6
AAA UK London 5
AAA India Bangalore 6
AAA India Delhi 9
ZZZ USA Chicago 7
ZZZ UK London 8
Expected Result
Phase Country City Value
AAA India Bangalore 6
AAA USA Chicago 3
ZZZ USA 7
ZZZ UK 8
I want to join this with my Main table which has Phase, Country and City, however the condition is
For Phase "ZZZ" i want to join only by Country where as for Phase "AAA" i want to join ty Country & City. Is is possible to do in SQL Query without a Stored procedure or temp tables
I am looking to achieve this in plain query. Thanks in advance!!!
SELECT *
FROM This_Table TT
LEFT JOIN Main_Table MT ON TT.Countrry = MT.Country
AND TT.Phase = 'ZZZ'
LEFT JOIN Main_Table MT2 ON TT.Countrry = MT2.Country
AND TT.City = MT2.City
AND TT.Phase = 'AAA'
This should do it:
WHERE
(a.phase = 'ZZZ' AND a.country = b.country)
OR
(a.phase = 'AAA' AND a.country = b.country AND a.city = b.city)

How to extract the higher values in sql query

I have a question about sql. If i have a table with some information like that:
City Code
New York | 10A
New York | 10A
New York | 20A
L.A | 20A
L.A | 20A
Washington | 30A
Washington | 30A
Washington | 20A
San Francisco | 20A
San Francisco | 20A
with the query: SELECT City, Code, COUNT(Code) FROM table GROUP BY City I can get the following result:
City Code Total
New York | 10A 2
New York | 20A 1
L.A | 20A 2
Washington | 30A 2
Washington | 20A 1
San Francisco | 20A 2
The question is: How can I extract only the lines with higher total in each city?
Assuming SQL Server or a DBMS that has ranking functions:
SELECT *
FROM (SELECT City, Code,
COUNT(Code) Count_,
RANK() OVER (PARTITION BY City ORDER BY COUNT(*) DESC) Rank_
FROM #test
GROUP BY City,Code
) sub
WHERE Rank_ = 1 ;
This will return all tying entries, for example in case of a 3-way tie for Denver, you'd get the following:
DEN 10A 1, DEN 20A 1, Den 30A 1
Tested in SQL-Fiddle. Works in Oracle, Postgres, SQL-Server.
this worked for me:
SELECT y.city, z.code, z.total
FROM (SELECT city, MAX(total) AS total
FROM (SELECT city, code, COUNT(code) AS total
FROM tableName
GROUP BY city, code) AS x
GROUP BY city) AS y INNER JOIN
(SELECT city, code, COUNT(code) AS total
FROM tableName
GROUP BY city, code) AS z
ON y.city = z.city AND y.total = z.total
if there is a tie it will return all the rows that tied.

Joining SQL lookup table with data table

I have a lookup table say cities with fields CityId, CityName
CityId CityName
1 New York
2 San Francisco
3 Chicago
I have an orders table which has fields: CityId, CustId, CompletedOrders, PendingOrders
CityId CustId CompletedOrders PendingOrders
1 123 100 50
2 123 75 20
I want a table/report that lists orders details of a given customer in all cities, i.e. the result I need is:
CityId CityName CustId CompletedOrders PendingOrders
1 New York 123 100 50
2 San Francisco 123 75 20
3 Chicago 123 0 0
How to do that ?
SELECT
c.CityId
c.CityName
o.CustId,
o.CompletedOrders
o.PendingOrders
FROM cities c
LEFT JOIN orders o ON ( c.CityId = o.CityId )
This will return all the rows that you want, but for the rows that don't exist in details it will return NULL values, so you would get:
CityId CityName CustId CompletedOrders PendingOrders
1 New York 123 100 50
2 San Francisco 123 75 20
3 Chicago 123 NULL NULL
The solution to get 0 instead depends on your database. With MySQL use IFNULL, with Oracle use NVL.
try this
select c.CityId,c.CityName,o.CustId,o.CompletedOrders,o.PendingOrders
from orders Left join cities
on o.CityId = c.CityId