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...
Related
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
I'm using SQL Server and I have a column called "Full Name" that I pulled from a separate table. I have a column for First Name & Last name (among many other columns).
Here is the code that I found and used and it worked:
SELECT Full_Name,
LEFT(Full_Name,CHARINDEX(' ',Full_Name )-1) AS First_Name,
RIGHT(Full_Name, LEN(Full_Name)- CHARINDEX(' ', Full_Name)) AS Last_Name
FROM table_name
That extracted the name, but upon viewing the entire table using this command:
SELECT * FROM table_name
I don't see it? Is there a method that I can use to insert the data into the First_name and Last_name columns without adding any additional Rows
Thank you !
Perhaps creating a view wil be sufficient:
CREATE VIEW table_name_v
SELECT Full_Name,
LEFT(Full_Name,CHARINDEX(' ',Full_Name )-1) AS First_Name,
RIGHT(Full_Name, LEN(Full_Name)- CHARINDEX(' ', Full_Name)) AS Last_Name
FROM table_name
Then instead of using the table name in subsequent queries you use the view instead
SELECT * FROM table_name_v
The problem you face otherwise is that if you add first and last name columns to this table that you now end-up with 3 columns to maintain, or that you may need to replace the data entry screen(s) that use full_name to start using first and last name columns instead.
If you really do want to proceed by adding the columns, you could try using "computed columns" which would avoid the necessity to change data entry screens etc.
CREATE TABLE mytable(
full_name VARCHAR(15) NOT NULL
);
INSERT INTO mytable(full_name) VALUES ('fred flintstone');
select * from mytable
full_name
fred flintstone
alter table mytable
add
first_name as LEFT(Full_Name,CHARINDEX(' ',Full_Name )-1)
, Last_Name as RIGHT(Full_Name, LEN(Full_Name)- CHARINDEX(' ', Full_Name))
select * from mytable
full_name
first_name
Last_Name
fred flintstone
fred
flintstone
db<>fiddle for computed columns here
If you realy do want to store these 2 separate columns (rather than computing them) then you need to add the columns to your table and run an update statement to populate them as follows:
alter table mytable
add
first_name varchar(100)
, last_name varchar(100)
update mytable
set
first_name = LEFT(Full_Name,CHARINDEX(' ',Full_Name )-1)
, Last_Name = RIGHT(Full_Name, LEN(Full_Name)- CHARINDEX(' ', Full_Name))
db<>fiddle for adding columns and updating here
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.
I am trying to combine to rows in a table into one new row in a table. Specifically columns First_Name and Last_name into First_Last. I am having trouble getting my query to run due to the fact I am trying to do this for all entries in the table and not just 1 row. Any suggestions?
Current Code:
update Name
set First_Last = (select First_Name + ' ' + Last_Name from Name)
Thanks,
Justin
Assuming you intend updating all rows on the same table using the First_Name and Last_Name values for each row, it is as simple as (in Sql Server):
update MyTable
set First_Last = First_Name + ' ' + Last_Name;
In most other RBDMS, you use the pipe || operator or the CONCAT function to combine text.
Note that most RDBMS also have the concept of a computed (sometimes called generated) column, which prevents the redundancy and synchronisation issues with storing a derived field:
CREATE TABLE MyTable...
(
First_Last AS first_name + ' ' + last_name
);
You did not specify your RDBMS but if you are using MySQL you can use the CONCAT() function
update Name
set First_Last = concat(First_Name, ' ', Last_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'