Select one of each - sql

How can I get all the countries from the DB, from this table:
city | country | info
Jerusalem | Israel | Capital
Tel Aviv | Israel |
New York | USA | Biggest
Washington DC | USA | Capital
Berlin | Germany | Capital
How can I get, using SQL, the countries only: Israel, USA, Germany?

Which database server are you using?
Assuming that the top row is the column name and you are using MySQL then you should be able to just do
"SELECT distinct(country) FROM <table-name>;"
This is probably in the documentation for the database software that you are using.

Related

Oracle SQL Concatenate string based of value of another column

I have tried looking up this issue but maybe I'm just not searching correctly.
I was wondering if its possible in SQL to concatenate based off the results of another column in the same row.
Let me give an example
+-------------+------------+--------+
| STATE | CITY | Region |
+-------------+------------+--------+
| Georgia | Atlanta | East |
| Los Angeles | California | West |
+-------------+------------+--------+
Lets say I have this table and I want to make a new column in it by doing some kind of concatenation
The output should look like this
+-----------+------------+-------------+--------+
| SIDE | STATE | CITY | Region |
+-----------+------------+-------------+--------+
| East_Side | Georgia | Atlanta | East |
| West_Side | California | Los Angeles | West |
+-----------+------------+-------------+--------+
So the Side column should look into region and ask What Region is it? And then say ok so this is "?_Side" Then concatenate the appropriate "Region_Side" = "East_Side"
This is just a simple example, I know in this example I could use a case statement but in my actual application I can't since its a lot of "Regions"
Is this possible or no?
Does this do what you want?
select Region || '_Side', state, city, region
from t;
|| is the string concatenation operator in Oracle (and in standard SQL as well).
Just use column and concat the string
select region ||'_Side', STATE , CITY , Region
from my_table

Postgresql - conditional statement to refer to other columns

I currently have a dataset that looks like this:
Personid | Question | Response
1 | Name | Daniel
1 | Gender | Male
1 | Address | New York, NY
2 | Name | Susan
2 | Gender | Female
2 | Address | Boston, MA
3 | Name | Leonard
3 | Gender | Male
3 | Address | New York, NY
I also have another table that looks like this (just the person id):
Personid
1
1
1
2
2
2
3
3
3
I want to write a query to return something like this:
Personid | Name | Gender | Address
1 |Daniel | Male | New York, NY
2 | Susan | Female | Boston, MA
3 |Leonard | Male | New York, NY
I think it's a mix of some sort of "transpose" (not sure if it's even available in SQL) and conditional statement on just the gender, but I'm having issues with getting the end result. Could anyone offer any advice?
Easiest way is just to link to the question table three times with different aliases.
select
p.person_id,
n.response as name,
g.response as gender,
a.response as address
from
person p
join question n
on n.personid = p.personid and n.question = 'Name'
join question g
on g.personid = p.personid and g.question = 'Gender'
join question a
on a.personid = p.personid and a.question = 'Address'
I'm assuming that your person table only has 3 rows not the 9 you've listed. if there are really 9, then just do a select distinct.
This is a textbook example of a pivot table. In postgresql it is implemented by the CROSSTAB function, which is available from the TABLEFUNC additional extension module.
If your need is really as simple as the provided MCVE, multiple JOIN’s might be enough, but in more complicated situations CROSSTAB is really the way to go, and worth the pain of installing an additional module, if it is not installed by default by your distro. In short, if your initial table is called dataset, and personid is an INT:
-- To execute as superuser. Be sure you have installed the extension
-- package. Execute once to install, it will stay in your database
-- ever since.
CREATE EXTENSION TABLEFUNC;
-- As normal user
SELECT * FROM CROSSTAB($$
SELECT personid, question, response FROM dataset
$$) AS ct(person INT, name TEXT, gender TEXT, address TEXT);
person | name | gender | address
--------+----------+---------+---------------
1 | Daniel | Male | New York, NY
2 | Susan | Female | Boston, MA
3 | Leonard | Male | New York, NY
(3 rows)
You can add WHERE clauses, JOIN with other tables, etc., according to your needs.

Sybase, show all rows but don't display column data when duplicate

Product: Sybase ASE 11/12/15/16
I am looking to update a Stored Procedure that gets called by different applications, so changing the application(s) isn't an option. What is needed is best explained in examples:
Current results:
type | breed | name
------------------------------------
dog | german shepherd | Bernie
dog | german shepherd | James
dog | husky | Laura
cat | british blue | Mr Fluffles
cat | other | Laserchild
cat | british blue | Sleepy head
fish | goldfish | Goldie
What I need is for the First column's data to be cleared on duplicates. For example, the above data should look like:
type | breed | name
------------------------------------
dog | german shepherd | Bernie
| german shepherd | James
| husky | Laura
cat | british blue | Mr Fluffles
| other | Laserchild
| british blue | Sleepy head
fish | goldfish | Goldie
I know I can do a cursor, but there are around 10,000 records and that doesn't seem proficient. Looking for a select command, don't want to change the data in the database.
After mulling over this, I found a solution that would work and not use a cursor.
select Type,breed,name
into #DontDisplay
from #MyDataList as a1
group by breed
Having breed= (select max(name)
from #MyDataList a2
where a1.breed= a2.breed)
order by breed, name
select n.Type,d.Breed,d.Name
from #MyDataList as d
left join #DontDisplay as n
on d.Breed= n.Breed and d.Name= n.Name
order by Breed
Works great and the solution was based on another solution Sybase SQL Select Distinct Based on Multiple Columns with an ID

Zend Framework: How to combine three tables in one query using Joins?

I have three tables like this:
Person table:
person_id | name | dob
--------------------------------
1 | Naveed | 1988
2 | Ali | 1985
3 | Khan | 1987
4 | Rizwan | 1984
Address table:
address_id | street | city | state | country
----------------------------------------------------
1 | MAJ Road | Karachi | Sindh | Pakistan
2 | ABC Road | Multan | Punjab | Pakistan
3 | XYZ Road | Riyadh | SA | SA
Person_Address table:
person_id | address_id
----------------------
1 | 1
2 | 2
3 | 3
Now I want to get all records of Person_Address table but also with their person and address records like this by one query:
person_id| name | dob | address_id | street | city | state | country
----------------------------------------------------------------------------------
1 | Naveed | 1988 | 1 | MAJ Road | Karachi | Sindh | Pakistan
2 | Ali | 1985 | 2 | ABC Road | Multan | Punjab | Pakistan
3 | Khan | 1987 | 3 | XYZ Road | Riyadh | SA | SA
How it is possible using zend? Thanks
The reference guide is the best starting point to learn about Zend_Db_Select. Along with my example below, of course:
//$db is an instance of Zend_Db_Adapter_Abstract
$select = $db->select();
$select->from(array('p' => 'person'), array('person_id', 'name', 'dob'))
->join(array('pa' => 'Person_Address'), 'pa.person_id = p.person_id', array())
->join(array('a' => 'Address'), 'a.address_id = pa.address_id', array('address_id', 'street', 'city', 'state', 'country'));
It's then as simple as this to fetch a row:
$db->fetchRow($select);
In debugging Zend_Db_Select there's a clever trick you can use - simply print the select object, which in turn invokes the toString method to produce SQl:
echo $select; //prints SQL
I'm not sure if you're looking for SQL to do the above, or code using Zend's facilities. Given the presence of "sql" and "joins" in the tags, here's the SQL you'd need:
SELECT p.person_id, p.name, p.dob, a.address_id, street, city, state, country
FROM person p
INNER JOIN Person_Address pa ON pa.person_id = p.person_id
INNER JOIN Address a ON a.address_id = pa.address_id
Bear in mind that the Person_Address tells us that there's a many-to-many relationship between a Person and an Address. Many Persons may share an Address, and a Person may have more than one address.
The SQL above will show ALL such relationships. So if Naveed has two Address records, you will have two rows in the result set with person_id = 1.

MySQL world database Trying to avoid subquery

I'm using the MySQL WORLD database.
For each Continent, I want to return the Name of the country with the largest population.
I was able to come up with a query that works. Trying to find another query that uses join only and avoid the subquery.
Is there a way to write this query using JOIN?
SELECT Continent, Name
FROM Country c1
WHERE Population >= ALL (SELECT Population FROM Country c2 WHERE c1.continent = c2.continent);
+---------------+----------------------------------------------+
| Continent | Nanme |
+---------------+----------------------------------------------+
| Oceania | Australia |
| South America | Brazil |
| Asia | China |
| Africa | Nigeria |
| Europe | Russian Federation |
| North America | United States |
| Antarctica | Antarctica |
| Antarctica | Bouvet Island |
| Antarctica | South Georgia and the South Sandwich Islands |
| Antarctica | Heard Island and McDonald Islands |
| Antarctica | French Southern territories |
+---------------+----------------------------------------------+
11 rows in set (0.14 sec)
This is the "greatest-n-per-group" problem that comes up frequently on StackOverflow.
SELECT c1.Continent, c1.Name
FROM Country c1
LEFT OUTER JOIN Country c2
ON (c1.continent = c2.continent AND c1.Population < c2.Population)
WHERE c2.continent IS NULL;
Explanation: do a join looking for a country c2 that has the same continent and a greater population. If you can't find one (which is indicated by the outer join returning NULL for all columns of c2) then c1 must be the country with the highest population on that continent.
Note that this can find more than one country per continent, if there's a tie for the #1 position. In other words, there could be two countries for which no third country exists with a greater population.