I have a table called delegation_table as follows:
delegator | delegatee
josh | ryan
carl | nick
sam | john
There is another table called permission_table as follows:
username | location | branch | office
josh | usa |New York | downtown
carl | asia | India | north
sam | usa |California| midtown
For each of the delegators from the delegation_table, I want to get their details from the permission_table and insert a row with the same details with username as the respective delegatee.
For example - I want to find details of josh which is:
josh | usa |New York | downtown
and insert this row in the permission_table:
ryan | usa |New York | downtown
Something like this:
insert into permission_table
(username, location, branch, office)
select 'ryan' as username, location, branch, office
from permission_table
where username = 'josh'
But I don't want to hard code the values and want to run this for every delegator in delegation_table. How do I do that??
This seems like a join:
insert into permission_table (username, location, branch, office)
select dt.delegatee, location, branch, office
from permission_table pt join
delegation_table dt
on dt.delegator = pt.username;
Related
This is the exercise:
How can you output a list of all members, including the individual who recommended them (if any)? Ensure that results are ordered by (surname, firstname).
The solution is below only I don't understand why it's 'ON recs.memid = mems.recommendedby' and not 'mems.memid = recs.recommendedby'. Why doesn't the latter work? I want to correct my thinking on how to use a Left Outer Join to itself.
CREATE TABLE members (
memid SERIAL PRIMARY KEY,
firstname VARCHAR(20),
surname VARCHAR(20),
recommendedby INTEGER References members(memid)
);
SELECT
mems.firstname AS memfname,
mems.surname AS memsname,
recs.firstname AS recfname,
recs.surname AS recsname
FROM
cd.members AS mems
LEFT OUTER JOIN cd.members AS recs
ON recs.memid = mems.recommendedby
ORDER BY memsname, memfname;
Consider this data:
MEMID | FIRSTNAME | SURNAME | RECOMMENDEDBY
------|-----------|---------|--------------
1 | John | Smith | null
2 | Karen | Green | 1
3 | Peter | Jones | 1
Here John recommended both Karen and Peter, but no one recommended John
'ON recs.memid = mems.recommendedby' (The one that "works")
You're getting a list of members and the ones that recommended them. Any member can only have been recommended by one member as per the table structure, so you'll get all the members just once. You're taking the recommendedby value and looking for it in the memid column in the "other table":
recommendedby --|--> memid of members that recommended them
MEMID | FIRSTNAME | SURNAME | RECOMMENDEDBY
------|-----------|---------|--------------
Karen | Green | John | Smith
Peter | Jones | John | Smith
John | Smith | null | null
The recommendedby column only has John (1), so when looking for the value 1, John comes up.
'ON mems.memid = recs.recommendedby' (The one that doesn't work)
You'll again get all the members. But here you're getting them as the ones doing the recommending, so to say. If they didn't recommend anyone, the paired record will be blank. This is because you're taking the memid value and looking to see if it matches the recommendedby column of the "other table". If a member recommended more than one, the record will appear multiple times:
memid --|--> recommendedby
MEMID | FIRSTNAME | SURNAME | RECOMMENDEDBY
------|-----------|---------|--------------
Karen | Green | null | null
Peter | Jones | null | null
John | Smith | Karen | Green
John | Smith | Peter | Jones
Karen and Peter didn't recommend anyone, but John recommended both the others.
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.
I have Two tables in Postgresql and I'm trying to get the number of times a hashtag is repeated by place.
I've made this query:
SELECT tweets_with_location.user_location,
tweets_with_location.my_new_id,
all_hashtags_with_location.regexp_split_to_table
FROM tweets_with_location, all_hashtags_with_location
WHERE tweets_with_location.my_new_id = all_hashtags_with_location.my_new_id;
Which returns the Location, the tweet id and the hashtag:
USER_LOCATION | MY_NEW_ID | HASHTAG
New York, NY | 33 | Happy
New York, NY | 40 | BigApple
Bronx, NY | 12 | Happy
Bronx, NY | 45 | Happy
Queens, NY | 23 | Trump
Queens, NY | 20 | Trump
Then, I've made another SQL Query but it seems it doesn't sums up the number of times a hashtag was displayed by place, the Count value is always 1:
SELECT tweets_with_location.user_location,
all_hashtags_with_location.regexp_split_to_table,
COUNT(DISTINCT all_hashtags_with_location.regexp_split_to_table) AS CountOf
FROM tweets_with_location, all_hashtags_with_location
WHERE tweets_with_location.my_new_id = all_hashtags_with_location.my_new_id
GROUP BY tweets_with_location.user_location,
all_hashtags_with_location.regexp_split_to_table
ORDER BY CountOf DESC;
I need is this result:
USER_LOCATION - HASHTAG - COUNT
New York, NY | Happy | 1
Bronx, NY | Happy | 2
Queens, NY | Trump | 2
New York, NY | Happy | 1
How do I do this? What is wrong with my SQL Query?
Or just remove the DISTINCT qualifier in the COUNT() function.
You were really close, you are counting the wrong field:
SELECT tweets_with_location.user_location,
all_hashtags_with_location.regexp_split_to_table,
COUNT(DISTINCT tweets_with_location.my_new_id) AS CountOf
FROM tweets_with_location, all_hashtags_with_location
WHERE tweets_with_location.my_new_id = all_hashtags_with_location.my_new_id
GROUP BY tweets_with_location.user_location,
all_hashtags_with_location.regexp_split_to_table
ORDER BY CountOf DESC;
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.
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.