What is wrong with my PSQL view table? - sql

I have two tables player and match:
CREATE TABLE player(
id serial PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL
);
CREATE TABLE match(
id serial PRIMARY KEY,
winner serial REFERENCES player(id) NOT NULL,
loser serial REFERENCES player(id) NOT NULL CHECK (loser != winner)
);
CREATE SEQUENCE playerid_sequence
start 1
increment 1;
CREATE SEQUENCE matchid_sequence
start 1
increment 1;
I want to create a view table that joins the two tables:
CREATE VIEW matchplayers AS
SELECT winner.name, loser.name, m.id
from player winner, player loser, match m
WHERE m.winner = winner.id AND m.loser = loser.id;
But it is returning an error that "name" has been mentioned more than once. Fairly inexperienced to SQL

Try
CREATE VIEW matchplayers AS
SELECT winner.name as winner_name, loser.name as loser_name, m.id
from player winner, player loser, match m
WHERE m.winner = winner.id AND m.loser = loser.id;
to get unambiguous column names of the view.

Related

Postgres query all results from one table blended with conditional data from another table

I have 2 SQL tables and I'm trying to generate a new table with data from the 2 tables.
Jobs table:
jobs (
id SERIAL PRIMARY KEY,
position TEXT NOT NULL,
location TEXT NOT NULL,
pay NUMERIC NOT NULL,
duration TEXT NOT NULL,
description TEXT NOT NULL,
term TEXT NOT NULL,
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL
)
Applied table:
applied (
id SERIAL PRIMARY KEY,
completed BOOLEAN DEFAULT FALSE,
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
job_id INTEGER REFERENCES jobs(id) ON DELETE SET NULL,
UNIQUE (user_id, job_id)
);
The tabled populated with data look like this:
Jobs table
Applied table
I want my final query to be a table that matches the jobs table but that has a new column called js_id with true or false based on whether the user has applied to that job. I want the table to look like this:
Here is the query I came up with to generate the above table:
SELECT DISTINCT on (jobs.id)
jobs.*, applied.user_id as applicant,
CASE WHEN applied.user_id = 1 THEN TRUE
ELSE FALSE END as js_id
FROM jobs
JOIN applied on jobs.id = applied.job_id;
However this doesn't work as I add more applicants to the table. I get different true and false values and I haven't been able to get it working. When I remove DISTINCT on (jobs.id) my true values are consistent but I wind up with a lot more than the 3 jobs I want. Here are the results without the DISTINCT on (jobs.id):
I think you want exists:
SELECT j.*,
(exists (select 1
from applied a
where a.job_id = j.id and a.user_id = 1
) as js_id
FROM jobs j;

How to update a column in a table A using the value from another table B wherein the relationship between tables A & B is 1:N by using max() function

I have two tables namely loan_details and loan_his_mapping with 1:N relationship. I need to set the hhf_request_id of loan_details table by the value which is present in the loan_his_mapping table for each loan.
Since the relationship is 1:N , I want to consider the record for each loan from loan_his_mapping table with two conditions mentioned below. The table definitions are as follows:
CREATE TABLE public.loan_details
(
loan_number bigint NOT NULL,
hhf_lob integer,
hhf_request_id integer,
status character varying(100),
CONSTRAINT loan_details_pkey PRIMARY KEY (loan_number)
);
CREATE TABLE public.loan_his_mapping
(
loan_number bigint NOT NULL,
spoc_id integer NOT NULL,
assigned_datetime timestamp without time zone,
loan_spoc_map_id bigint NOT NULL,
line_of_business_id integer,
request_id bigint,
CONSTRAINT loan_spoc_his_map_id PRIMARY KEY (loan_spoc_map_id),
CONSTRAINT fk_loan_spoc_loan_number_his FOREIGN KEY (loan_number)
REFERENCES public.loan_details (loan_number) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION );
The joining conditions while updating are:
The Records of loan_details with hhf_lob = 4 and status='Release'
I should consider that record for updating value among 'N' number of records from loan_his_mapping table with value max(loan_spoc_map_id) for each loan.
The query I have right now
update lsa_loan_details ldet
set hhf_request_id = history.request_id
from loan_his_mapping history
where ldet.loan_number = history.loan_number and ldet.status='Release' and ldet.hhf_lob=4 and
history.line_of_business_id=4 ;
I want to know how to use that record for each loan from loan_his_mapping with max(loan_spoc_map_id) to update column of loan_details table. Please Assist!
You need a sub-query to fetch the row corresponding to the highest loan_spoc_map_id
Something along the lines:
update loan_details ldet
set hhf_request_id = history.request_id
from (
select distinct on (loan_spoc_map_id) loan_number, request_id
from loan_his_mapping lhm
where lhm.line_of_business_id = 4
order by loan_spoc_map_id desc
) as history
where ldet.loan_number = history.loan_number
and ldet.status = 'Release'
and ldet.hhf_lob = 4;

How to create a table with ONE existing row from another table?

I'm frankly new to sql and this is a project I'm doing.
I would like to know if there's a way to connect one column in one table to another table when creating tables. I know of the join method to show results of, but I want to minimized my code as possible.
CREATE TABLE players (
id INT PRIMARY KEY, -->code I want connect with table match_record
player_name CHARACTER
);
CREATE TABLE match_records (
(id INT PRIMARY KEY /*FROM players*/), --> the code I want it to be here
winner INT,
loser INT
);
CREATE TABLE players (
id INT not null PRIMARY KEY, -->code I want connect with table match_record
player_name CHARACTER
);
CREATE TABLE match_records (
id INT not null PRIMARY KEY references players(id), --> the code I want it to be here
winner INT,
loser INT
);
this way you restrict that match_records.id is only from players.id:
t=# insert into match_records select 1,1,0;
ERROR: insert or update on table "match_records" violates foreign key constraint "match_records_id_fkey"
DETAIL: Key (id)=(1) is not present in table "players".
So I add players:
t=# insert into players(id) values(1),(2);
INSERT 0 2
And now it allows insert:
t=# insert into match_records select 1,1,0;
INSERT 0 1
update
https://www.postgresql.org/docs/current/static/app-psql.html#APP-PSQL-PROMPTING
%#
If the session user is a database superuser, then a #, otherwise a >.
(The expansion of this value might change during a database session as
the result of the command SET SESSION AUTHORIZATION.)
in this way:
CREATE TABLE new_table as SELECT id,... from old_table where id = 1;

invalid identifier when executing select in oracle

I am trying to execute a select in oracle that uses 3 tables, nba_player, nba_team, and nba_team_roster. nba_player includes player data with a player_id and nba_team includes team information with a team_id. nba_team_roster is an associative entity and includes a player_id and team_id to associate the two. I want this query to return the first and last name of each player on team 'OKC' but for some reason it gives me the error below. I am not sure why this isn't executing properly. Any help would be greatly appreciated.
select nba_player.first_name, nba_player.last_name
from nba_player,nba_team
join nba_team_roster
on nba_team_roster.player_id=nba_player.player_id
where nba_team_roster.team_id= nba_team.team_id
and nba_team.team_name='OKC';
on nba_player.player_id=nba_team_roster.player_id
*
ERROR at line 4:
ORA-00904: "NBA_PLAYER"."PLAYER_ID": invalid identifier
CREATE TABLE NBA_Team(
team_id number primary key,
team_name varchar(5)
);
CREATE TABLE NBA_Player(
player_id number primary key,
first_name varchar(10),
last_name varchar (11),
position varchar(3),
salary number,
points_per_game number
);
CREATE TABLE NBA_Team_Roster(
roster_ID number primary key,
team_id number,
player_id number unique,
foreign key (team_id) references NBA_Team(team_id),
foreign key (player_id) references NBA_Player(player_id)
);
Simple rule: Never use commas in the FROM clause. Always use proper, explicit JOIN syntax. That will solve your problem and make the query easier to understand:
select p.first_name, p.last_name
from nba_player p join
nba_team_roster r
on r.player_id = p.player_id join
nba_team t
on r.team_id = t.team_id
where t.team_name = 'OKC';
Note that I also introduced table aliases. These make the query easier to write and to read.

Why does this query only select a single row?

SELECT * FROM tbl_houses
WHERE
(SELECT HousesList
FROM tbl_lists
WHERE tbl_lists.ID = '123') LIKE CONCAT('% ', tbl_houses.ID, '#')
It only selects the row from tbl_houses of the last occuring tbl_houses.ID inside tbl_lists.HousesList
I need it to select all the rows where any ID from tbl_houses exists within tbl_lists.HousesList
It's hard to tell without knowing exactly what your data looks like, but if it only matches the last ID, it's probably because you don't have any % at the end of the string, so as to allow for the list to continue after the match.
Is that a database in zeroth normal form I smell?
If you have attributes containing lists of values, like that HousesList attribute, you should instead be storing those as distinct values in a separate relation.
CREATE TABLE house (
id VARCHAR NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE list (
id VARCHAR NOT NULL,
PRIMARY KEY (id),
);
CREATE TABLE listitem (
list_id VARCHAR NOT NULL,
FOREIGN KEY list_id REFERENCES list (id),
house_id VARCHAR NOT NULL,
FOREIGN KEY house_id REFERENCES house (id),
PRIMARY KEY (list_id, house_id)
);
Then your distinct house listing values each have their own tuple, and can be selected like any other.
SELECT house.*
FROM house
JOIN listitem
ON listitem.house_id = house.id
WHERE
listitem.list_id = '123'