Sorry the title isn't clear
I have a script (using Pl/Sql Oracle), i have created a report that will optout a list of cities chosen by a user. I have a column that will list that city but i wanted to include an additional column that list other cities associated with the user (the cities list should not include his/her pick on that column).
I am not exactly sure who to do that so that the additional column will not list the picked city or cities. Is there a function i can use?
I am also doing it on Crystal reporting 10 (if it possible there)
Iex: This is just an idea of what i am trying to do.
##Table Name: Giving Cities##
##Andrew - Peru##
##Andrew - Venezuela##
##Andrew - France##
##Paul - USA##
Pick cities where user = Andrew and City = Peru
Output
User, City, Other Given Cities
In SQL adding extra additional columns:
select user,cities,'' as additional_columns from yourtable
I think this is what you are looking for: SQL Query to concatenate column values from multiple rows in Oracle
It looks like exactly what you are trying to do with concatenating the results of multiple rows together.
As for not selecting the "selected" city for the additional column, you would want to use a subselect. A subselect allows you to apply a different where clause to the additional column.
select t.user, t.city, t2.concatenated_cities
from table t
inner join
(
select distinct <see above link for how to concatenate rows here> as concatenated_cities
from table sub_t
where sub_t.city <> 'CITY'
) t2
on t.user = t2.user
where t.city = 'CITY'
Related
Using Standard ANSI SQL, how does one return a list of columns which are matching for two specific rows of data? We don't know the names of the columns, only the table name and the ID (or other primary key) to pick out the two specific rows we wish to compare?
Let's say we have a table with a large number of columns for real estate listings. If I choose two specific rows like so:
SELECT *
FROM listing_data
WHERE mls_number IN ('111111', '222222')
How can I identify the names of all other columns which happen to match between these two particular rows?
For example, perhaps there is a column called 'school_district' and they both are in the same district. Or perhaps the two listings share the same street name, or the same listing agent, or all three of these.
To get column names you can select from information_schema.columns however that is a table of column names only and does not have any data. If you are trying to do a select * from tablex where select * from tabley where columnname = 'value' then if it works at all unless your tables are small it may take hours to complete. It is simple if you know your column names to form up a query. Do some research and practice query on your tables and you should get some insight. You are unlikely to have address data in a name column so once you get familiar with your data you should be able to craft a simple query.
You need to explicitly do the comparison for each column. One method is:
SELECT (CASE WHEN ld1.col1 IS NOT DISTINCT FROM ld.col1 THEN 'col1;' ELSE '' END ||
CASE WHEN ld1.col2 IS NOT DISTINCT FROM ld.col2 THEN 'col2;' ELSE '' END ||
. . .
) as matches
FROM listing_data ld1 JOIN
listing_data ld2
ON ld1.mls_number = '111111' AND
ld2.mls_number = '222222'
What my issue is:
I am constantly returning multiple values when I don't expect to. I am attempting to get a specific climate, determined by the state, county, and country.
What I've tried:
The code given below. I am unsure as to what is wrong with it specifically. I do know that it is returning multiple values. But why? I specify that STATE_ABBREVIATION = PROV_TERR_STATE_LOC and with the inner joins that I do, shouldn't that create rows that are similar except for their different CLIMATE_IDs?
SELECT
...<code>...
(SELECT locations.CLIMATE_ID
FROM REF_CLIMATE_LOCATION locations, SED_BANK_TST.dbo.STATIONS stations
INNER JOIN REF_STATE states ON STATE_ID = states.STATE_ID
INNER JOIN REF_COUNTY counties ON COUNTY_ID = counties.COUNTY_ID
INNER JOIN REF_COUNTRY countries ON COUNTRY_ID = countries.COUNTRY_ID
WHERE STATE_ABBREVIATION = PROV_TERR_STATE_LOC) AS CLIMATE_ID
...<more code>...
FROM SED_BANK_TST.dbo.STATIONS stations
I've been at this for hours, looking up different questions on SO, but I cannot figure out how to make this subquery return a single value.
All those inner joins don't reduce the result set if the IDs you're testing exist in the REF tables. Apart from that you're doing a Cartesian product between locations and stations (which may be an old fashioned inner join because of the where clause).
You'll only get a single row if you only have a single row in the locations table that matches a single row in the stations table under the condition that STATE_ABBREVIATION = PROV_TERR_STATE_LOC
Your JOINs show a hierarchy of locations: Country->State->County, but your WHERE clause only limits by the state abbreviation. By joining the county you'll get one record for every county in that state. You CAN limit your results by taking the TOP 1 of the results, but you need to be very careful that that's really what you want. If you're looking for a specific county, you'll need to include that in the WHERE clause. You get some control with the TOP 1 in that it will give the top 1 based on an ORDER BY clause. I.e., if you want the most recently added, use:
SELECT TOP 1 [whatever] ORDER BY [DateCreated] DESC;
For your subquery, you can do something like this:
SELECT TOP 1
locations.CLIMATE_ID
FROM REF_CLIMATE_LOCATION locations ,
SED_BANK_TST.dbo.STATIONS stations
INNER JOIN REF_STATE states ON STATE_ID = states.STATE_ID
INNER JOIN REF_COUNTY counties ON COUNTY_ID = counties.COUNTY_ID
INNER JOIN REF_COUNTRY countries ON COUNTRY_ID = countries.COUNTRY_ID
WHERE STATE_ABBREVIATION = PROV_TERR_STATE_LOC
Just be sure to either add an ORDER BY at the end or be okay with it choosing the TOP 1 based on the "natural order" on the tables.
If you are expecting to have a single value on your sub-query, probably you need to use DISTINCT. The best way to see it is you run your sub-query separately and see the result. If you need to include other columns from the tables you used, you may do so to check what makes your result have multiple rows.
You can also use MAX() or MIN() or TOP 1 to get a single value on the sub-query but this is dependent to the logic you want to achieve for locations.CLIMATE_ID. You need to answer the question, "How is it related to the rest of the columns retrieved?"
Given the schema here I'm trying to understand and solve the below 3 sql queries as I'm confused:
1- Present a table giving the names of the countries with ≥ 50% urbanization
rates, their urbanization rates, and their per capita GDP. Note that
urbanization rate is the percentage of population living in cities. Do not
count cities with NULL values for population.
SELECT country.name, round(sum(city.population)/country.population, 3) AS urban, round(gdp/country.population, 3) AS gdppc
FROM city
INNER JOIN country ON code = country
INNER JOIN economy ON code = economy.country
WHERE city.population IS NOT NULL
GROUP BY country.name, country.population, economy.gdp
HAVING round(sum(city.population)/country.population, 3) >= 0.5
ORDER BY urban DESC;
In the above query, Why I need to include country.population and economy.gdp in the GROUP BY? If I tried using just country.name in the GROUP BY I get an error saying I should include the others.
2- Show organizations that have as members all the European countries with over 50 million people?
SELECT name
FROM organization
INNER JOIN (SELECT organization
FROM country
INNER JOIN encompasses
ON code = encompasses.country
INNER JOIN ismember
ON code = ismember.country
WHERE population > 50000000 AND continent = 'Europe'
GROUP BY organization
HAVING count(ismember.country) = (SELECT count(*)
FROM country
INNER JOIN encompasses
ON code = country
WHERE population > 50000000 AND continent = 'Europe'))
AS innerQuery
ON abbreviation = innerQuery.organization;
Why I need the HAVING Part above?
3- Insert a new organization called “Tivoli” and a trigger that says if Germany joins “Tivoli” then so too must the UK and France. Insert Germany into the “Tivoli” organization. Confirm proper behavior.
I tried the below script but it's not working, any advice please?
do $$
begin
IF(NOT EXISTS ( SELECT 1 FROM organization WHERE organization."name" = 'Tivoli' AND organization.country = 'D' ))
BEGIN
INSERT INTO organization VALUES ('Tivoli','Tivoli organization',NULL,'F',NULL,NULL);
INSERT INTO organization VALUES ('Tivoli','Tivoli organization',NULL,'GB',NULL,NULL);
END;
end $$
1)
You used country.population and economy.gdp in the select, outside of aggregate functions ( COUNT(), AVG() and SUM() ), and you have a GROUP BY. Everything that you select has to be in GROUP BY or inside of aggregate functions.
2)
Because you were asked to show organizations that have ALL of 50mil + people countries. With HAVING, you check if that organization has the right amount of countries.
3)
organization."name" = 'Tivoli'
It's supposed to be :
organization.name
First of all, you should limit a question to one only, not 3. But here are some pointers for all 3:
In the above query, Why I need to include country.population and economy.gdp in the GROUP BY? If I tried using just country.name in the GROUP BY I get an error saying I should include the others.
This is a requirement. A group by country.name alone would work (in Postgres 9.1+) only if the other two fields are known to be functionally dependent on country.name. But probably country.name is not the primary key of the country table, so in theory it is possible to have two records in that table with the same name, but different population.
The rule is as follows:
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions or if the ungrouped column is functionally dependent on the grouped columns, since there would otherwise be more than one possible value to return for an ungrouped column. A functional dependency exists if the grouped columns (or a subset thereof) are the primary key of the table containing the ungrouped column.
This is implemented since version 9.1.
Why I need the HAVING Part above?
Because a condition on an aggregate (count in this case) can only be performed after grouping, and can thus not be expressed in the where clause. In this case the having clause makes sure that the organisation is not only present in some big EU Member States, but all big EU Member states.
I tried the below script but it's not working, any advice please?
Without a proper database schema, it is not possible to provide you with the correct SQ, but from the ERD diagram it seems that the organization table does not have a country field. Instead the ismember table connects organizations with countries. You would only insert one organization, but several ismember records (one per Member State involved)
It is better also to name the fields in your insert statement, so it is clear which value corresponds to which field.
I am kind of new to SQL and I made a couple of tables to practice. The columns may have some unrelated categories but I don't know what else write...
Anyway, basically what i want to do is get info from two tables based on the first and last name from one table.
Here are my tables:
Order
Host
I want create a query to pull the ticket number, height, order, subtotal and total by first and last name. The only orders I want to pull are from John Smith And Sam Ting. So in the end, I want my extraction to have the following columns:
Ticket Number
First Name
Last Name
Height
Order
Subtotal
Total
Any help or direction would be awesome!
With the assumption the tables both have unique Ticket_Numbers and that will provide a one-to-one mapping between then.
SELECT
Order.Ticket_Number,
First_Name,
Last_Name,
Height,
Order,
Subtotal,
Total
FROM Order
JOIN Host on Host.Ticket_Number = Order.Ticket_Number
WHERE
(First_Name = 'John' AND Last_Name = 'Smith')
OR (First_Name = 'Sam' AND Last_Name = 'Ting')
You need to "call" the table name first, and then the column. After that you need to use the "join" for the 2 tables. And finally you need the "where". I didn't look for the details so you need to check the "names".
SELECT Order.Ticket_Number, Order.First_Name, Order.Last_Name, Order.Height, Order.Order, Cost.Subtotal, Cost.Total
FROM Order
INNER JOIN Cost
where First_Name="Jhon" and Last_Name="blablabla"
or
First_Name="SecondGuy" and Last_Name="blablabla"
In my tables I have for example
CountyID,County and CityID in the county table and in the city table I have table I have for example
City ID and City
How do I create a report that pulls the County from the county table and pulls city based upon the cityid in the county table.
Thanks
Since this is quite a basic question, I'll give you a basic answer instead of the code to do it for you.
Where tables have columns that "match" each other, you can join them together on what they have in common, and query the result almost as if it was one table.
There are also different types of join based on what you want - for example it might be that some rows in one of the tables you're joining together don't have a corresponding match.
If you're sure that a city will definitely have a corresponding county, try inner joining the two tables on their matching column CityID and querying the result.
The obvious common link between both tables is CityID, so you'd be joining on that. I think you have the data organized wrong though, I'd put CountryID in the City table rather than CityID in the country table. Then, based on the CountryID selected, you can limit your query of the City table based on that.
To follow in context of Bridge's answer, you are obviously new to SQL and there are many places to dig up how to write them. However, the most fundamental basics you should train yourself with is always apply the table name or alias to prevent ambiguity and try to avoid using column names that might be considered reserved words to the language... they always appear to bite people.
That said, the most basic of queries is
select
T1.field1,
T1.field2,
etc with more fields you want
from
FirstTable as T1
where
(some conditional criteria)
order by
(some column or columns)
Now, when dealing with multiple tables, you need the JOINs... typically INNER or LEFT are most common. Inner means MUST match in both tables. LEFT means must match the table on the left side regardless of a match to the right... ex:
select
T1.Field1,
T2.SomeField,
T3.MaybeExistsField
from
SomeTable T1
Join SecondTable T2
on T1.SomeKey = T2.MatchingColumnInSecondTable
LEFT JOIN ThirdTable T3
on T1.AnotherKey = T3.ColumnThatMayHaveTheMatchingKey
order by
T2.SomeField DESC,
T1.Field1
From these examples, you should easily be able to incorporate your tables and their relationships to each other into your results...