I have 2 tables: batters and pitchers
I want to pull
playerid(nvarchar50), firstname(nvarchar50), lastname(nvarchar50), bats(nvarchar50)
from the batters table
and
playerid(nvarchar50), firstname(nvarchar50), lastname(nvarchar50), throws(nvarchar50)
from the pitchers table
I want to combine the output so that when i get results it comes out like this
playerid, firstname, lastname, throws, bats
Is this possible? I'm guessing it should be but I've exhausted joins and unions and cant get the result set to come out that way. Remember they are two different tables
bat table
playerID nameFirst nameLast bats
----------------------------------------
abreubo01 Bobby Abreu L
abreujo02 Jose Abreu R
abreuto01 Tony Abreu B
ackledu01 Dustin Ackley L
adamecr01 Cristhian Adames S
adamsla01 Lane Adams R
adamsma01 Matt Adams L
pit table
playerid nameFirst nameLast throws
------------------------------------------
abadfe01 Fernando Abad L
aceveal01 Alfredo Aceves R
achteaj01 A.J. Achter R
adamsau01 Austin Adams R
adamsmi03 Mike Adams R
adcocna01 Nathan Adcock R
affelje01 Jeremy Affeldt L
Desired Result
pit table
playerid nameFirst nameLast throws Bats
------------------------------------------------
abadfe01 Fernando Abad
aceveal01 Alfredo Aceves
achteaj01 A.J. Achter
adamsau01 Austin Adams
adamsmi03 Mike Adams
adcocna01 Nathan Adcock
affelje01 Jeremy Affeldt
Assumptions:
1) You just want a list of all the players without any restrictions
2) The same player ID never appears in both tables (or if it does, you don't care if they're listed twice)
Based on those assumptions, you can simply write:
SELECT playerID, nameFirst, nameLast, bats, NULL as throws
FROM bats
UNION ALL
SELECT playerID, nameFirst, nameLast, NULL as bats, throws
FROM pits
However, I think your data is not fully normalised. Both of these tables are actually lists of players, just with a slight variation in their attributes. So a more sensible overall approach would be simply to have a single "players" table with columns as follows:
playerID, nameFirst, nameLast, bats, throws
Bats and throws would both be nullable, in case the player doesn't do that action. If necessary you could add an extra "player_type" column to denote their role (batter, pitcher - or both, if that's allowed).
Once you've got that structure, the query is trivial:
SELECT playerID, nameFirst, nameLast, bats, throws
FROM players
Related
I'm working on an assignment where the question is:
"List all of the actor names, semi-colon separated, that acted in the same movie. Your final list should
include both the movie title and semi-colon separated actor names"
Currently I have
SELECT title, name as actor FROM (SELECT *, count(*) OVER (partition by movies.movieid) as count FROM actors
JOIN movieroles on actors.actorid = movieroles.actorid
JOIN movies on movieroles.movieid = movies.movieid)X
WHERE X.count>1
GROUP BY title, actor;
which outputs
title | actor
------------------------------------+-----------------------
The Terminator | Arnold Schwarzenegger
The Terminator | Michael Biehn
Sherlock Holmes: A Game of Shadows | Jude Law
The Terminator | Linda Hamilton
Sherlock Holmes: A Game of Shadows | Rachel McAdams
However, I need to produce
"title" "actor"
------------------------------------------------------------------------------
Sherlock Holmes: A Game of Shadows Jude Law;Rachel McAdams
The Terminator Linda Hamilton;Michael Biehn;Arnold Schwarzenegger
So my question is how would one approach reversing the split_part or a similar function of sorts to give desired output?
Just STRING_AGG() function is needed with ; argument as a separator with grouping by title column :
SELECT title, STRING_AGG(DISTINCT name, ';') as actors
FROM actors a
JOIN movieroles mr ON a.actorid = mr.actorid
JOIN movies m ON m.movieid = mr.movieid
GROUP BY title;
and an optional order by clause might be used
( syntax : STRING_AGG ( expression, separator [order_by_clause] ) ) .
Aliasing tables would be elegant for readability of the query as a later reference.
FYI I use Redshift SQL.
I have a database that looks roughly like the one below (the database has multiple columns that I'll abstract away for simplicity).
This table is a representation of the hierarchical tree within my organization.
employee manager
-------- -------
daniel louis
matt martha
martha kim
laura matt
michael martha
...
As you can see, matt appears in two distinct records, one as the employee and the other as laura's manager. Martha appears in three records, one as an employee and in two other as manager.
I'd like to find a way to compute the number of direct reports each employee has. A conditional count in which the criteria would be where employee = manager, perhaps?
I guess I could find this information using a subquery and then join it back but I was wondering if there was a more "elegant" way to do this making use of window functions maybe.
The expected output for the table above would be:
employee manager direct_reports
-------- ------- --------------
daniel louis 0
matt martha 1
martha kim 2
laura matt 0
michael martha 0
...
I would approach this with a correlated subquery:
select
t.employee,
t.manager,
(select count(*) from mytable t1 where t1.manager = t.employee) direct_reports
from mytable t
This should be a quite efficient method, especially with an index on (employee, manager).
Use a left join and aggregation:
select em.employee, em.manager, count(ew.employee)
from employees em left join
employees ew
on ew.manager = em.employee
group by em.employee, em.manager;
I have a counselling appointment website. Currently I list clients in one table, but also have couples listed by id in a second table for when they book a couples session. ie:
client
id_no first last
564 John Smith
983 Mary Jones
999 Mark Fields
882 Joan Hancock
couple
id_no client1 client2
623 564 983
555 999 882
I would like to write a single select statement, using aliases, which will list out couples on a single line. Up until now, I have been doing a simple join then cleaning up the result using php after running the query, but would like to clean this up in sql so that I get a result like the following
id_no first_1 last_1 first_2 last_2
623 John Smith Mary Jones
555 Mark Fields Joan Hancock
I suspect that sub queries might be involved, but can't for the life of me wrangle them to get this result.
Update
I just tried the following:
SELECT id_no,first_1,last_1,first_2,last_2
FROM ( SELECT a.id_no AS id_no, b.first AS first_1,b.last AS last_1
FROM couple AS a, client AS b WHERE a.client1=b.id_no ) c1
JOIN ( SELECT a.id_no AS id_no, b.first AS first_2,b.last AS last_2
FROM couple AS a, client AS b WHERE a.client2=b.id_no ) c2 ON
(c1.id_no=c2.id_no)
And am getting a message that "Column 'id_no' in field list is ambiguous". Not sure if I am on the right track
You are getting the exception because you did not specified the table alias to id_no as this column belongs to both tables, so SQL is not sure which column to return, so it will throw ambiguous column error.
Also you don't have to use sub queries, you just need to join client table twice with couple table, one for client1 and other one for client2 like below
Select cp.id_no,
cl1.first as first_1,
cl1.last as last_1,
cl2.first as first_2,
cl2.last as last_2
From couple cp
inner join client cl1 on cl1.id_no = cp.client1
inner join client cl2 on cl2.id_no = cp.client2
Imagine I have a query called QueryA that returns stuff like this:
Employee Description Rank
John Happy 1
John Depressed 3
James Happy 1
James Confused 2
Mark Depressed 3
I am trying to make a query that grabs the Employee and the Description, but only one description -- the one with the best "rank." (the lower the rank the better). I sort QueryA by Employee then by Rank (descending).
So I'd want my new query QueryB to show that John as Happy, James as Happy, and Mark as Depressed.
However I try selecting Employee and then First of Description and it doesn't always work.
I'm not able to check this for Access, but it should work fine. Check my SQL Fiddle
select
r.employee, d.description
from
table1 as d
inner join (select min(rank) as rank, employee
from
table1
group by employee) r on d.rank = r.rank
and d.employee = r.employee
Can I use a table column within a Like operator? I've created an example,
TableA
Names Location
Albert Smith Senior Aberdeen
John Lee London
Michael Rogers Junior Newcastle
Mary Roberts Edinburgh
TableB
Names
Albert Smith
John Lee
Michael Rogers
I want to do a query such as:
SELECT TableA.Location
into NewTable
FROM TableA
WHERE TableA.Names Like '*[TableB.Names]*';
In this case, there would be no match for Mary Roberts, Edinburgh but the first three locations would be returned.
Is it possible to put a column into a like statement?
If not does anyone have any ideas how I could do this?
Hope you can help
PS I can't use an actual asterisk since this is removed and the text italicised, also I have read about using % instead but this has not worked for me.
You can join the two tables and use LIKE within the JOIN clause:
SELECT TableA.Location
into NewTable
FROM TableA
INNER JOIN TableB ON TableA.Names LIKE TableB.Names & '*';
Honestly, I had no idea that you can do this in Access before I tried it just now :-)