PostgreSQL multi-table query with name, first_name, and last_name - sql

I have two tables in my PostgreSQL database.
One table, call it 'Archive', has a column 'name' which are two-word first-name and last-name, e.g. 'John Smith' and an empty column which wants to be full of 'user_id'.
The second table, call it 'User Accounts', has three columns, one 'first_name' and one 'last_name' and one 'id'.
My goal is to implement a query that uses the column in Archive to select for the corresponding first_name and last_name in User Accounts and return to Archive the 'id' into 'user_id' column

You can use a join. For instance:
select a.*, ua.id as user_id
from archive a left join
user_accounts ua
on a.name = ua.first_name || ' ' || ua.last_name;
If you actually want to update the column:
update archive a
set user_id = ua.id
from user_accounts ua
where a.name = ua.first_name || ' ' || ua.last_name;
Note that name matching can be quite tricky. You may not get as many matches as you expect. If this turns out to be an issue, ask another question. Include sample data and desired results in the question.

Related

Cannot Query NULL or Empty Values in a Field or column in a table

I have a query that is 99% working, but I cannot query NULL or empty records for
dbo.HUR_STAFF_DEMOGRAPHICS.DEMOGRAPHICS_POSITION = '' OR
dbo.HUR_STAFF_DEMOGRAPHICS.DEMOGRAPHICS_POSITION IS NULL
I tried both, but the SQL statement below returns no rows if I add the lines above. However it DOES query rows for ALL staff that have a location and or position entered into the database, but my goal is to query this information for all staff that have a location and or position in the database, or if have a location and or position is NULL or BLANK (empty).
I queried the Demographics table alone, and I get a total of 1120 records, I also calculated the columns that have BLANK or NULL (so no position title or Location) and that is 316 records.
Sure enough, when I run this query I get 804 records returned, which means the query is not querying Null or empty columns for Location or Position Title.
Can anyone see why the query will not return the null columns?
SELECT DISTINCT
dbo.HUR_STAFF_DEMOGRAPHICS.employee_no,
first_name, last_name, PREFERRED_NAME,
location,
DEMOGRAPHICS_POSITION,
EMPLOYEE_EMAIL,
Location_name,
Description
FROM
dbo.HUR_STAFF_DEMOGRAPHICS,
dbo.HUR_STAFF_INTERLINK,
dbo.HUR_LOCATION,
dbo.HUR_POSITION_CODE,
dbo.HUR_EMAIL_ADDRESS
WHERE
dbo.HUR_STAFF_DEMOGRAPHICS.employee_no = dbo.HUR_STAFF_INTERLINK.employee_no
AND dbo.HUR_STAFF_DEMOGRAPHICS.location = dbo.HUR_LOCATION.Location_no
AND dbo.HUR_STAFF_DEMOGRAPHICS.DEMOGRAPHICS_POSITION = dbo.HUR_POSITION_CODE.POSITION_CODE
AND dbo.HUR_STAFF_DEMOGRAPHICS.EMPLOYEE_NO = dbo.HUR_EMAIL_ADDRESS.EMPLOYEE_NO
AND dbo.HUR_STAFF_DEMOGRAPHICS.employee_status = 'A'
AND dbo.HUR_STAFF_DEMOGRAPHICS.DEMOGRAPHICS_POSITION IS NULL
ORDER BY
last_name
Thanks in advance for your time and expertise.
I believe your issue is that you are joining to the DEMOGRAPHICS_POSITION table on DEMOGRAPHICS_POSITION = POSITION_CODE, but are also looking for DEMOGRAPHICS_POSITION = '' or DEMOGRAPHICS_POSITION = NULL values. Assuming that the DEMOGRAPHICS_POSITION table has no empty code entry, the join to that table will fail for both of these conditions and no record will be returned.
The solution is to change that join to a LEFT JOIN, but the query must be first rewritten to use ANSI join syntax.
Using table aliases is also a good practice to simplify the statement and improve readability.
Try:
SELECT DISTINCT D.employee_no,
first_name,
last_name,
PREFERRED_NAME,
location,
DEMOGRAPHICS_POSITION,
EMPLOYEE_EMAIL,
Location_name,
Description
FROM HUR_STAFF_DEMOGRAPHICS D
JOIN HUR_STAFF_INTERLINK I
ON D.employee_no = I.employee_no
JOIN HUR_LOCATION L
ON D.location = L.Location_no
LEFT JOIN HUR_POSITION_CODE P
ON D.DEMOGRAPHICS_POSITION = P.POSITION_CODE
JOIN HUR_EMAIL_ADDRESS E
ON D.EMPLOYEE_NO = E.EMPLOYEE_NO
WHERE D.employee_status = 'A'
AND (D.DEMOGRAPHICS_POSITION = '' OR D.DEMOGRAPHICS_POSITION IS NULL)
ORDER BY last_name
Alternately, for this particular usage, you can drop the HUR_POSITION_CODE join entirely, along with the corresponding select list references (Is that where Description comes from?)

Why do I get an error querying from column alias? [duplicate]

This question already has answers here:
Using an Alias column in the where clause in Postgresql
(6 answers)
access a column aliases in the where clause in postgresql
(2 answers)
How to use new created column in where column in sql?
(2 answers)
Closed 1 year ago.
I'm getting an error querying from the column alias and don't understand why. In the example below, if I run a query from the actual column, no problem. I concatenate first_name and last_name columns into a fullname column alias and then get the output.
SELECT first_name ||' '|| last_name AS fullname
FROM actor;
Output:
Now, if I create a column alias, I get the error. In this example, I'm concatenating first_name and last_name into a fullname column alias, and then query the names between value1 and value2.
SELECT first_name ||' '|| last_name AS fullname
FROM actor;
WHERE fullname BETWEEN 'Zero Cage' AND 'Fred Costner';
Output:
Thanks in advance for your taking the time to help!
In postgres document:
An output column's name can be used to refer to the column's value in ORDER BY and GROUP BY clauses, but not in the WHERE or HAVING clauses; there you must write out the expression instead.
That's according to the SQL standard and may not be very intuitive. The (historic) reason behind this is the sequence of events in a SELECT query. WHERE and HAVING are resolved before column aliases are considered, while GROUP BY and ORDER BY happen later, after column aliases have been applied.
Also note that conflicts between input and output names are resolved differently in ORDER BY and GROUP BY - another historic oddity (with a reason behind it, but potentially confusing nonetheless).
You can use one of the below manners:
Use full both column name
SELECT first_name || ' ' || last_name AS fullname
FROM actor
WHERE first_name || ' ' || last_name BETWEEN :conditio1 AND :conditio2
Use CTE
WITH data s (
SELECT first_name || ' ' || last_name AS fullname
FROM actor
)
SELECT *
FROM data
WHERE fullname BETWEEN :conditio1 AND :conditio2
Use subquery
SELECT *
FROM (
SELECT first_name || ' ' || last_name AS fullname
FROM actor
) tmp
WHERE tmp.fullname BETWEEN :conditio1 AND :conditio2

Update statement is only inserting one value

I have data in one table (OWNER) i'm trying to use to update the data in another table (TAX_BILL_INFO). I've written an update statement to take the value from one column (owner.ownername) and insert that value into another column (tax_bill_info.mailername) where they have the same ID (taxbillid). below is my statement that I used:
UPDATE TAX_BILL_INFO
SET Mailername = OWNER.Ownername
FROM TAX_BILL_INFO INNER JOIN
OWNER ON TAX_BILL_INFO.TaxBillID = OWNER.TaxBillID
where taxyear = '2013' and (mailername = '' or mailername = ' ' or mailername is null) and (purchasername = '' or purchasername = ' ' or purchasername is null)
The columns are updating, it is only putting the FIRST value from OWNER into EVERY column in tax_bill_info. (ex. john smith, john smith, john smith). Are my where criteria throwing this off? Or could it be something else?
EDIT
If I use this select query:
select owner.OwnerName
FROM owner INNER JOIN
TAX_BILL_INFO ON TAX_BILL_INFO.TaxBillID = OWNER.TaxBillID
the names pull as they should. If i do a select query from the table I need the data entered into, it gives me the same dupliacte name for every row:
SELECT MAILERNAME
FROM TAX_BILL_INFO INNER JOIN
OWNER ON TAX_BILL_INFO.TaxBillID

How Do I SELECT when needing to use LIKE and change column Name

Here is the problem I am working on:
Select all the Oracle database employees whose last names end with ā€œsā€ Change the
heading of the column to read Possible Candidates.
I tried
SELECT last_name AS possible_candidates FROM * WHERE last_name LIKE '%s';
That returned the error :
ORA-00903: invalid table name
Unless I am reading the question wrong how do I check the entire database for something like this?
To answer the question which is asking for employee names not just last names you would select all employees with a last name that ends in S.
SELECT *
FROM employees
WHERE last_name LIKE '%s'
If the table has more than a first_name and last_name column you can do
SELECT first_name, last_name
FROM employees
WHERE last_name LIKE '%s'
Now to combine your two parts (Select employees and rename column)
Run one of the two queries above but add an AS statement as show in the example below.
SELECT *
AS Possible_Candidates
FROM employees
WHERE last_name LIKE '%s'
Based on feedback: this appears to be your answer...
Is there a table called employees? if that I would interpret the question as from the employees table. Otherwise, you could select table_name from All_TAB_COLS where column_name like = 'LAST_NAME' and then build a union from the resulting tables all of which have a field called 'LAST_NAME'

Updating rows based on a multiple column condition

I'm trying to update some rows in a table based on two other columns in another table. As a toy model, consider two tables: People, with columns first_name, last_name, and has_license; Drivers, with columns first_name and last_name. Now I want to update the first table so has_license='Y' for all tuples of first_name and last_name that are also in the Drivers table.
I could do:
UPDATE people SET has_license='Y'
WHERE first_name + last_name IN (SELECT first_name + last_name FROM drivers)
(In my actual query, first_name and last_name are an externally-set record id and a date, and the subquery is more complex involving a join/EXCEPT clause.)
That's clumsy and has possible errors depending on the values. Ideally I could just make the tuple in sql like so:
UPDATE people SET has_license='Y'
WHERE (first_name, last_name) IN (SELECT first_name, last_name FROM drivers)
But that's invalid SQL (according to SQLite). So is what I want even possible?
(One other problem is that none of the tables have any primary keys, especially not single-column ones. If that weren't the case, I would use that to simply identify the row.)
This is SQL
Just use a JOIN!
UPDATE people
SET has_license='Y'
FROM People
INNER JOIN Drivers
ON Drivers.First_name = people.first_name
AND Drivers.Last_name = people.last_name
In SQL Server I would just use aliases but I'm not familiar with the intricacies of SQLite syntax. This should be valid AFAIK.
EDIT
Below version uses EXISTS:
UPDATE people
SET has_license='Y'
WHERE EXISTS (SELECT 1 FROM Drivers
WHERE Drivers.First_name = people.first_name
AND Drivers.Last_name = people.last_name)
I think you can concatenate the fields:
...first_name + last_name) IN (SELECT first_name + last_name...
Or
...first_name + ' : ' + last_name) IN (SELECT first_name + ' : ' + last_name...