Postgres Retrieve Values Conditionally? - postgresql

not sure if my title is exactly waht I want to accomplish but it was a guess. I'm trying to see if something like the following is possible in PGSQL.
Basically, I have a set of data that I want to pull no matter what. But, if certain columns of data arent null, then I want it to join another table and pull data referencing that data. So, for example, let's say I have data like:
User_Accounts:
userid
companyname
first name
25df
Test Company 1
Bob
921f
Test Company 1
Lawrence
882s
Company test 2
NULL
8234
Test Company 1
Cleo
8244s
Company test 2
Paul
825q
Test Company 1
Bruce
5552
B Alpha Company
Lenny
Baseball_Rosters:
userid
baseball_team
company
position
25df
Atlanta Aliens
Test Company 1
P
882s
Boston Bruisers
Company test 2
DH
8234
California Craisins
Test Company 1
1B
8244s
Tampa Titans
Company test 2
P
null
Tampa Titans
Test Company 1
P
5552
Tampa Titans
B Alpha Company
2B
5552
Tampa Titans
B Alpha Company
SS
921f
California Craisins
Test Company 1
P
825q
Boston Bruisers
Test Company 1
P
How would I perform a query to get a result like:
userid
baseball_team
company
first name
position
null
Tampa Titans
Test Company 1
null
P
25df
Atlanta Aliens
Test Company 1
Bob
P
825q
Boston Bruisers
Test Company 1
Bruce
P
921f
California Craisins
Test Company 1
Lawrence
P
So essentially, inserting the firstname & lastname field if and only if userid is not null? And then to order by userid null first and then in order? Thanks for the help.

This looks like a LEFT OUTER JOIN.
Like this:
SELECT baseball_rosters.user_id, baseball_team, comapny, first_name, position
FROM baseball_rosters
LEFT OUTER JOIN user_accounts ON user_accounts.user_id = baseball_rosters.user_id;

Related

Relational Division Issue to Solve for Total

I have a table of Card holders and the amount of each cards they have.
I'm trying to query to get a result of Full Card Set holders and how many sets they each have.
The data is simular to below:
**Cards **
Card
User
Count
AA
1234
2
BB
1234
2
CC
1234
2
DD
1234
1
AA
4321
1
BB
4321
1
CC
4321
1
AA
3321
3
BB
2221
1
CC
2221
4
**Card Sets **
Card
Set
AA
SetA
BB
SetA
CC
SetA
If looking for "SetA" I would expect below.
**Results **
User
TotalSets
1234
2
4321
1
I know this is possibly a Relational Division solution but not sure how to get the count of sets per Card Holder.
This is what I was using before I needed total sets:
`SELECT
cs.[Set],
tc.User
FROM Cards tc
JOIN (
SELECT *,
Total = COUNT(*) OVER (PARTITION BY CardSets.[Set])
FROM CardSets cs
) ts ON tc.Card = cs.Card
GROUP BY
cs.[Set], tc.User
HAVING COUNT(*) = MIN(cs.Total);`
A blind try, please provide us a create table/insert script for convenience:
select
c.[user]
,cs.[set]
-- if any cs row
,fullsets=
min(case when c.card is null then 0 else 1 end) -- if card missing for a set, set this flag to 0 to absorb results
*
min(c.[count])
from
cardsets cs
left join cards c on c.card=cs.card -- if a card belongs to multiple sets, you'll need to add here: and cs.[set]='SetA'
group by c.[user],cs.[set]

How to hidden value when it doesn't match

I'm in a trouble like this:
For a following table A with data
|ID| |Department| |Name|
1 IT JOHN
3 IT JOHN
5 IT JOHN
1 SALE LINH
3 SALE LINH
2 SALE LINH
3 CLERK MINA
6 CLERK MINA
4 CLERK MINA
There are some ROLEID, each ROLEID has role corresponding, such as 1 is Manager,2 is leader...
I want to select based on ROLEID, if exist ROLEID = 3, all values has department is IT won't display. How can I do that?

Select a specific row from a table with duplicated entries based on one field

I have a table which holds data in the following format, however I would like to be able to create a query that checks whether the reference number is duplicated and only return the entry with the latest date_issued.
ref_no name gender place date_issued
xgb/358632/p John Smith M London 02.08.2016
Xgb/358632/p John Smith M London 14.06.2017
Rtu/638932/k Jane Doe F Birmingham 04.09.2017
The result from the query should be;
ref_no name gender place date_issued
Xgb/358632/p John Smith M London 14.06.2017
Rtu/638932/k Jane Doe F Birmingham 04.09.2017
Is there a fairly straightforward solution for this?
assuming the date column is type date or timestamp
select distinct on(ref_no) * from tablename order by refno,date desc;
this works beacuse distinct on supresses rows with duplicates of the expression in parenthese.

Query to match multiple column values with multiple rows

I have the following table in my postgresql 9.1
Table contact:
contact_id phone mobile
1 123 456
2 111 222
3 333 123
4 222 444
Table role:
contact_fk exchange
7 1
8 2
1 4
5 5
2 4
4 5
I need the result like:
contact_id phone mobile exchange
1 123 456 4
3 333 123 4
2 111 222 4
I want all the contact data whose mobile field data is in any other contacts phone field and the user must be in exchange 4, which is available in contact_role table
FYI: the contact table contains around 50k rows so joining the contact table to itself taking a lot time, so we must apply the contact_role condition together.
Joining 50k table with 2 columns (where contact_fk is probably primary) shouldn't take long time.
SELECT t1.contact_id, t1.phone, t1.mobile, t2.exchange
FROM contact as t1
JOIN role as t2 ON t1.contact_id = t2.contact_fk
WHERE t2.exchange = 4
Or if you have index on exchange column, this probably will be faster:
SELECT t1.exchange, t2.contact_id, t2.phone, t2.mobile
FROM role as t1
JOIN contact as t2 ON t1.contact_fk = t2.contact_id
WHERE t1.exchange = 4
Here is the answer
select t1.contact_id,
t1.phone,
t1.mobile,
t2.phone,
t2.exchange
from contact t1
inner join (select contact_id,
mobile,
phone,
exchange
from contact, contact_role
where contact.contact_id = contact_fk
and exchange = 4
) t2
on t1.mobile = t2.phone
and t1.mobile != '';

Return all records regardless if there is a match

In my Table 1, It may have AND have a null entry in the address column to corresponding record OR not have a matching entry in Table 2.
I want to present all the records in Table 1 but also present corresponding entries from Table 2. My RESULT is what I am trying to achieve.
Table 1
ID First Last
1 John Smith
2 Bob Long
3 Bill Davis
4 Sam Bird
5 Tom Fenton
6 Mary Willis
Table 2
RefID ID Address
1 1 123 Main
2 2 555 Center
3 3 626 Smith
4 4 412 Walnut
5 1
6 2 555 Center
7 3
8 4 412 Walnut
Result
Id First Last Address
1 John Smith 123 Main
2 Bob Long 555 Center
3 Bill Davis 626 Smith
4 Sam Bird 412 Walnut
5 Tom Fenton
6 Mary Willis
You need an outer join for this:
SELECT * FROM Table1 t1 LEFT OUTER JOIN Table2 t2 ON t1.ID = t2.RefID
How do you join those two tables? If table 2 have more than 1 matched address, how do you want display them? Please clarify in your question.
Here is a query based on my assumptions.
SELECT
ID, First, Last,
Address = (SELECT MAX(Address) FROM Table2 t2 WHERE t1.ID = t2.ID)
FROM Table1 t1