SQL Join 2 tables with different columns - sql

I am trying to create a single login function for usernames and password that exist across 2 tables.
Currently I have
SELECT * FROM CUSTOMER WHERE username = usernameIN AND password = passwordIN
SELECT * FROM STAFF WHERE username = usernameIN AND password = passwordIN
If there is a match ill log the user in.
Is there a query to join these 2 tables so I can run 1 SQL query on them.
Input tables
CUSTOMER
username,password,firstname,lastname,addressline1,town
andys,pass123,andy,smith,123 fake st,fake town
STAFF
username,password,firstname,lastname,position,salary
davidq,pass321,david,queen,manager,10000
Expected Output from SQL Query
OUTPUT TABLE
username,password,firstname,lastname,addressline1,town,position,salary
andys,pass123,andy,smith,123 fake st,fake town,null,null
davidq,pass321,david,queen,null,null,manager,10000

You need UNION ALL.
SELECT username,
password1,
firstname,
lastname,
addressline1,
town,
NULL AS manager,
NULL AS salary
FROM customer
UNION ALL
SELECT username,
password1,
firstname,
lastname,
NULL,
NULL,
POSITION,
salary
FROM staff;
You can add WHERE clauses to your individual queries accordingly.
More over if you want to avoid duplicate rows, use UNION
Result:
username password1 firstname lastname addressline1 town manager salary
--------------------------------------------------------------------------------------------------
andys pass123 andy smith 123 fake st fake town NULL NULL
davidq pass321 david queen NULL NULL manager 10000
DEMO

SELECT
username,password,firstname,lastname,addressline1,town, null as position, null as salary
FROM
CUSTOMER
WHERE username = usernameIN AND password = passwordIN
UNION ALL
SELECT
username,password,firstname,lastname, null, null, position,salary
FROM
STAFF
WHERE username = usernameIN AND password = passwordIN
You'll have to add aliases

You can join both the table using UNION like below.
SELECT username, password, firstname, lastname, addressline1, town, position, salary FROM
(SELECT username, password, firstname, lastname, addressline1, town, null position, null salary FROM CUSTOMER
UNION ALL
SELECT username, password, firstname, lastname, null addressline1, null town, position,salary FROM STAFF) AS t
WHERE t.username = 'username' AND t.password = 'password'

Use UNION
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

Related

Return the first and last name of customers whose email is not in the format of "<first_name>. <last_name>#email.org"

Hello I am new to sql and I have these question:
Return the first and last name of customers whose email is not in the format of "<first_name>.<last_name>#email.org".
and here is my code.
SELECT first_name, last_name
FROM customer
WHERE email LIKE '%<first_name>.%<last_name>%#email.org';
It returns me with 0 rows and columns where in fact all emails are in the correct format.
It seems I am wrong in my 'LIKE' statement.
Schema (PostgreSQL v13)
CREATE TABLE customer (
"first_name" VARCHAR(6),
"last_name" VARCHAR(5),
"email" VARCHAR(19)
);
INSERT INTO customer
("first_name", "last_name", "email")
VALUES
('bob', 'joe', 'bob.joe#gmail.com'),
('tom', 'larry', 'tom.larry#gmail.com'),
('little', 'foot', 'lilfeet#hotmail.com');
Query
SELECT first_name, last_name
FROM customer
WHERE email LIKE first_name || '.' || last_name || '%';
first_name
last_name
bob
joe
tom
larry
View on DB Fiddle
Did you try below? Also, adding a data sample would be helpful.
SELECT first_name, last_name
FROM customer
WHERE email NOT LIKE '%'||first_name||'.%'||last_name||'%#%.%';
You can also use a regular expression:
-- Any lines where email = first_name.last_name#
SELECT first_name, last_name FROM customer WHERE email ~ format('[%s]+[.]+[%s]+#',first_name,last_name)
-- Any lines where email = *.*#
SELECT first_name, last_name FROM customer WHERE email ~ '[\w]+[.]+[\w]+#'
Result:
first_name
last_name
bob
joe
tom
larry
Demo in DBfiddle

PostgreSQL: `VIEW` returns no rows with `SPLIT_PART()` columns

Problem Description:
Hi everyone, I'm having some troubles querying on a VIEW whose columns are, in part, the result of SPLIT_PART() function on og table's column; I created the VIEW as it follows:
CREATE VIEW ClientsAddressList(Client_ID, FirstName, LastName, ResidenceAddress, City, PostalCode, Province) AS
SELECT Client_ID,
FirstName,
LastName,
SPLIT_PART(Address, '-', 1) AS ResidenceAddress,
SPLIT_PART(Address, '-', 2) AS City,
SPLIT_PART(Address, '-', 3) AS PostalCode,
SPLIT_PART(Address, '-', 4) AS Province
FROM Clients;
My intention was to divide the structured attribute (Clients.Address defined as a string VARCHAR(255)) which contains all the informations releated to client's domicile in several columns to separately query (e.g. SELECT FirstName, LastName FROM ClientAddressList WHERE City LIKE 'N%'; or SELECT Client_ID FROM ClientAddressList WHERE PostalCode = '82305';).
What I experience:
The Clients table contains one test row:
Client_ID
FirstName
LastName
ResidenceAddress
City
PostalCode
Province
00451
Ezio
Auditore
Via dei Banchi 45 - Florence - 50123 - Florence
Florence
50123
Florence
So my VIEW has this row:
Client_ID
FirstName
LastName
ResidenceAddress
City
PostalCode
Province
00451
Ezio
Auditore
Via dei Banchi 45
Florence
50123
Florence
I've tried:
SELECT Client_ID, FirstName, LastName
FROM ClientsAddressList
WHERE City = 'Florence'
And it returns no result:
Client_ID
FirstName
LastName
ResidenceAddress
City
PostalCode
Province
But if I query on columns that are not the result of SPLIT_PART() it works:
SELECT Client_ID, FirstName, LastName, City
FROM ClientsAddressList
WHERE Client_ID = '00451'
Client_ID
FirstName
LastName
City
00451
Ezio
Auditore
Florence
What I expect:
I would WHERE clause to work and returns values even on SPLIT_PART() result columns:
SELECT Client_ID
FROM ClientAddressList
WHERE PostalCode LIKE = '%123'
Client_ID
00451
Can someone explain me what could be the problem, please? Thank you so much!
As sticky bit wrote: there are spaces around the values. There are two ways to deal with this. One way is to just slap a trim() around the expressions in the view:
trim(SPLIT_PART(Address, '-', 2)) AS City,
The other option is to use an appropriate regex to split the information to remove the whitespace during splitting:
select client_id,
firstname,
lastname,
address[1] as residenceaddress,
address[2] as city,
address[3] as postalcode,
address[4] as province
from (
select client_id, firstname, lastname,
regexp_split_to_array(residenceaddress, '\s*-\s*') as address
from clients
) t
Online example
In the long run you should fix your data model by properly normalizing it and storing those values in separate columns. I don't know how many city names contain dashes in Italy, but in Germany, this pattern would break quickly with city names like "Garmisch-Partenkirchen" or "Leinfelden-Echterdingen"

Return multiple roles for user in 1 column not multiple rows

SQL Server
I am trying to return 1 row for a user that contains their firstname, lastname, email etc and also all their roles contained in a separate roles table connected through UserRoles.
User -> UserRoles -> Role
------------- --------------- ------------
Email UserEmail Id
Firstname RoleId Name
Lastname
Phone
IsActive
declare #Email nvarchar(100);
set #Email = 'testemail#gmail.com'
SELECT [User].Email, Password, Username, Firstname, Lastname, Phone, IsActive, EmailVerified, IsBanned, BanStart, BanEnd, [Role].Name as Roles
FROM dbo.[User], [UserRole], [Role]
WHERE [User].Email = #Email AND UserRole.UserEmail = [User].Email AND UserRole.RoleId = Role.Id
Return
Email Username Firstname Lastname Phone IsActive EmailVerified IsBanned BanStart BanEnd Roles
testemail#gmail.com testemail#gmail.com daniel brownn 3199999999 1 0 0 NULL NULL Expert
testemail#gmail.com testemail#gmail.com daniel brownn 3199999999 1 0 0 NULL NULL User
This returns the correct info unfortunately for a user with 2 roles it returns 2 separate rows. I aim to have 1 row returned with a comma separated value in the Roles column containing both the roles values. Is this possible?
Thanks!
You can try to use JOIN clause and STRING_AGG method. Here you can find documentation of this method.
Your query result like this:
SELECT
[User].Email,
Password,
Username,
Firstname,
Lastname,
Phone,
IsActive,
EmailVerified,
IsBanned,
BanStart,
BanEnd,
STRING_AGG([Role].Name, ', ') as Roles
FROM
dbo.[User]
JOIN [UserRole] ON [UserRole].UserEmail = [User].Email
LEFT JOIN [Role] ON [Role].Id = [UserRole].RoleId
GROUP BY
[User].Email,
Password,
Username,
Firstname,
Lastname,
Phone,
IsActive,
EmailVerified,
IsBanned,
BanStart,
BanEnd
Note that STRING_AGG is a t-sql method, but there is something equivalent in MySQL (if I'm not wrong is GOUP_CONCAT here you can find something)

select distinct rows based on column values

In one table i have four columns 'FirstName' , 'LastName' , 'Dob', 'Number'
There are multiple rows for the unique 'first Name' and 'LastName' and they can have same or different 'Number' and 'Dob' values
FirstName LastName Dob Number
Alice Smith 02/03/77 0876543 (require)
Alice Smith Null 0876543 (Not require)
Alice Smith Null Null (Not require)
John Adam 11/28/63 3265783 (require)
John Adam 11/28/63 Null (Not Require)
John Adam 05/15/58 Null (require)
Sally Smith Null Null (require)
I want distinct rows, but I need only one record if either the 'Number'or the 'Dob' matches with other records of same FirstName' and 'LastName'
I am lookin for the rows that are labeled 'require' in the example above. The combinations i tried didn't get results i thought they would.
Thanks
I would first select all rows that have all four fields populated:
SELECT DISTINCT FirstName, LastName, Dob, Number
FROM customers
WHERE Dob IS NOT NULL And Number IS NOT NULL
Then I would add to the selection the records with NOT NULL values that do not exist in the first selection:
with RequiredSet as (
SELECT DISTINCT FirstName, LastName, Dob, Number
FROM customers
WHERE Dob IS NOT NULL And Number IS NOT NULL
), AdditionalSet as (
SELECT distinct c.FirstName, c.LastName, c.Dob, c.Number
FROM customers c
WHERE Dob IS NOT NULL And NOT EXISTS(SELECT 1
FROM RequiredSet r
WHERE r.FirstName = c.FirstName And r.LastName=c.LastName And r.Dob=c.Dob)
OR Number IS NOT NULL And NOT EXISTS(SELECT 1
FROM RequiredSet r
WHERE r.FirstName = c.FirstName And r.LastName=c.LastName And r.Number=c.Number)
)
SELECT FirstName, LastName, Dob, Number
FROM RequiredSet
UNION ALL
SELECT FirstName, LastName, Dob, Number
FROM AdditionalSet

Sql returns Column has "FristName LastName" as 1 string how to order by Lastname?

I'm using Oracle. My sql returns a column like this
Name:
John Smith
David Lee
...
If I do Order by Name, it will order by first name. How do I order by Last name? If I do Order by Lastname, Firstname oracle returns invalid identifiers. I tried substr, instr but it doesn't work. I know the sql is tedious but just want the data to quickly fix this issue.
Full SQL:
http://pastebin.com/hYkdHBDM
You say your SQL "returns a column" in that format. Do you mean the column is stored that way, or that it's stored as two fields and composed into one in the SQL statement?
If stored that way it's difficult to create an algorithm that will reliably determine what part of a multi-part name is the last name part (indeed, this is sometimes down to personal preference of the person owning the name).
If stored in two separate fields you should be able to ORDER BY LastName, FirstName depending on how the SQL is constructed and whether there are any intermediate views between you and the table. Please post the SQL and table structure.
First, in order to sort by LastName, it needs to be one of the columns you return in each of the queries in your Union All. Second, you can greatly simplify your query by using a common-table expression. Third, do not use the comma delimited syntax for Joins (e.g. From TableA, TableB, TableC...). Instead use the ISO Join syntax.
With RootQuery As
(
Select MeetingID
, FirstName || ' ' || LastName AS Name
, LastName
, CASE WHEN RSVP = 1 THEN 1 ELSE NULL END AS Yes
, CASE WHEN RSVP = 0 THEN 1 ELSE NULL END AS No
, CASE WHEN RSVP = 2 THEN 1 ELSE NULL END AS Phone
, CASE WHEN RSVP = -1 THEN 1 ELSE NULL END AS No_Reply
, MysteryTable0.Response1
, MysteryTable1.Response2
, Note
, groupname
From Attendance A
Join Allusers As B
And B.MemberId = A.PersonId
Join MembershipGroups As M
And M.MemberId = B.MemberID
Join (
SELECT TD.MEMBERID AS MEM0
, Response AS Response1
FROM TRACKINGDETAILS TD, ALLUSERS U
Where TD.MEMBERID = U.MEMBERID
And TD.TRACKINGID = 64
) MysteryTable0
On MysteryTable0.Mem0 = B.MemberId
Join (
SELECT TD.MEMBERID AS MEM1
, Response AS Response2
FROM TRACKINGDETAILS TD, ALLUSERS U
Where TD.MEMBERID = U.MEMBERID
And TD.TRACKINGID = 65
) As MysteryTable1
On MysteryTable1.Mem1 = B.MemberId
Where Meetingid = :1
)
Select MeetingId, Name, LastName, Yes, No, Phone, No_Reply
, Response1, Response2
, Note, GroupName
From RootQuery
Union All
Select Null, 'Total', LastName, SUM(Yes), SUM(No), SUM(Phone), SUM(No_Reply)
, TO_CHAR(SUM(Response1))
, TO_CHAR(SUM(Response2))
, NULL, Groupname
From RootQuery
Group By GroupName
Union All
Select Null, 'Grand Total', LastName, SUM(Yes), SUM(No), SUM(Phone), SUM(No_Reply)
, TO_CHAR(SUM(Response1))
, TO_CHAR(SUM(Response2))
,NULL, ' '
From RootQuery
Group By ???
Order By GroupName Desc, LastName Asc, Name Asc
Btw, the last query will probably have a problem in that it did not have a Group By (which I denoted with Group By ???) but you are using aggregate functions.
What Matthew PK said is correct however he failed to mention that INSTR can parse backwards in which case, his "fail" scenario would be resolved.
Here try this:
create table test_name (f_name varchar2(20), l_name varchar2(20), full_name varchar2(20));
insert into test_name (f_name, l_name, full_name) values ('John', 'Mellencamp', 'John 2Mellen');
insert into test_name (f_name, l_name, full_name) values ('John', 'Mellencamp', 'John C. 1Mellen');
select f_name, l_name, substr(full_name,instr(full_name,' ',-1,1)) as substr, full_name from test_name order by substr(full_name,instr(full_name,' ',-1,1));
Basically the money shot is: substr(full_name,instr(full_name,' ',-1,1))
If you know the field will always be "FirstName LastName" separated by a space you could:
ORDER BY RIGHT(Name, INSTR(Name,' '))
This is the number of characters, on the right side, starting at the space.
This will fail if any other names are separated by a space like "John Cougar Mellencamp"