If I have a query that returns first and last name, how would I go about combining them into 1 field?
I want to be able to select an id - then the first and last names are found based on that id, and then they are concatenated for the final returned string.
I am working on a complicated query with many columns being returned - in the past I've gone in with more queries afterwards and replaced some of the values using php. But I would like to have it all work in the original query.
Right now I'm doing something similar to this:
SELECT id From....etc
Then afterwards in php I do this query and replace the id with the returned values for first and last name
SELECT lastName, firstName FROM people, patient WHERE idpatient = $data AND people_id = id
the result is then changed from:
id:1 ---> id: lastname, firstname
is there a way to combine both of these queries into one?
For the first part of your question, use CONCAT
SELECT CONCAT( lastName, firstName ) AS full_name
FROM people, patient
WHERE idpatient = $data AND people_id = id
Also, you can rewrite this query using explicit JOINs
SELECT CONCAT( lastName, firstName ) AS full_name
FROM people
INNER JOIN patient ON people_id = id
WHERE idpatient = $data
If you're only interested in rows in people that have an entry in patient, or
SELECT CONCAT( lastName, firstName ) AS full_name
FROM people
LEFT JOIN patient ON people_id = id
WHERE idpatient = $data
if you're also interested in rows in people that might not have an entry in patient.
Related
I post this question here to get more clarity over my query while learning SQL
(The example is simplfied)
I have the following tables:
BookTable(bookID, isbn, title) // Holds every book, not the ammuont, just the writing
CopyTable(copyID, bookID) // Represent a physical copy
AuthorTable(authorID, fName, lName) // Represents an author
WriteTable(authorID, bookID) // Represents who wrote what
I want to select every author (Preferably like {authordID, fname, lname} ), if that author has a book written, which has more than 5 copies.
I am trying something like this:
SELECT DISTINCT authorID, fname, lname // My final "output table"
FROM T_Author
WHERE authorID IN
SELECT authorID, bookID
FROM T_Write
WHERE bookID IN
SELECT bookID, COUNT(*) AS count
FROM T_Copy
GROUP BY bookID // This part I doubt the most
WHERE count > 5
So my idea is:
Select every BookID that appears more than 5 times in CopyTable
Select every author that wrote any of those books from WriteTable
Write out the name of the author with data from AuthorTable
I am not able to test this if it acutally works, but is this the "Right" way to think in this problem?
Thanks in advance for any guidance.
You are pretty close. Try this:
SELECT a.authorID, a.fname, a.lname // My final "output table"
FROM T_Author a
WHERE a.authorID IN (SELECT w.authorID
FROM T_Write w
WHERE w.bookID IN (SELECT c.bookID
FROM T_Copy c
GROUP BY c.bookID // This part I doubt the most
HAVING COUNT(*) > 5
)
);
Notes:
Subqueries need their own parentheses.
For IN, the returned value has to exactly match what is being compared. In general, you cannot return two columns.
Use HAVING to filter after aggregation.
SELECT DISTINCT is not needed in the outer query. It just adds processing overhead.
Use table aliases and qualified column names in any query that has more than one table reference.
Here is the rule:
When comparing userId, only search userId starting with 'AB' and its matching duplicates (except 'AB'). Then get a list of "unique userId" by only returning above duplicated userId that is having 'AB' at the beginning.
For returned duplicated string starting with 'AB', we need to make sure there is "duplicate"; otherwise, we should not return 0 record
I know it sounds confusing, please see example below:
Table UserName with ten records, and its userId fields (10 records) are:
ABC1234
C1234
C12345
BC12345
BBC1234
ABF1235
F1235
ABY1236
BCD3456
D3456
Desired Result after running query:
ABC1234
ABF1235
Please note: Although ABY1236 starts with 'AB', this record should not be returned in output, since it doesn't have a "duplicate" match like Y1236 (ignoring first two character, 'AB').
I have a sample query below, but it only returned duplicated record NOT starting with 'AB', also it will return ABY1236.
SELECT distinct substr(userId , -(length(userID)-2))
from UserName where userId like 'AB%';
Thanks for the help!
You can use EXISTS to check if there is a userId that is equal to the right part of "AB.." starting from the 3d char:
select u.userId from UserName u
where
u.userId like 'AB_%'
and
exists (
select 1 from UserName where userId = substr(u.userId, 3)
)
You could try using a selct join for check only the matching result
SELECT substr(a.userId , -(length(a.userID)-2))
from UserName a
INNER JOIN UserName b ON a.substr(a.userId , -(length(a.userID)-2)) = b.UserId
AND userId like 'AB%'
I want to select all customers or one customer from same SP. Right now we are mantaining two SPs to get these details:
i.e. To get all customers:
select id, name from customers
and to get one customer:
select id, name from customers
where id=id_from_input
To make them common, i thought of pasing id_from_input as null to get all customers. I tried several ways to make a conditional where statement in my sql that would work with this plan, but nothing is working. For example:
select id, name from customers
where if(id_from_input <> null) id=id_from_input; end if
gives me syntax error.
How can I make a where clause that returns all rows when id_from_input is null, the matching row otherwise?
The expression x <> null is never true; you can only use is null, or is not null, to test for null. Correcting your attempt gives:
select id, name from customers
where id_from_input is null or id = id_from_input
Or for something more terse (and IMHO elegant):
select id, name from customers
where id = coalesce(id_from_input, id)
Use CASE Statement to achieve your result :
SELECT id, name FROM customers WHERE id = CASE WHEN ISNULL(id_from_input,'')
<> '' THEN id_from_input ELSE id END
Try to use or:
select id, name
from customers
where id_from_input is null or id = id_from_input
if id_from_input is null then or clause will not be calculated.
Try this query
select id, name from customers where
CASE WHEN id_from_input<>null THEN id=id_from_input
ELSE id END
Having the following query where i am trying to search in a query, i might be writing a wrong syntax, but i am not sure how to correct it. I want to search for the text in the main table and the subquery table too.
here is my query
select mytable.*
from mytable
where spam = 0
and deleted = 0
and draft = 0
and (subject like '%guss%' or body like '%guss%' or
(select CONCAT(users.firstname,' ', users.lastname) as fname,users.email
from users where firstname like '%guss%' or lastname like 'guss'))
and id = 24
order by id desc
getting this Error
[Err] 1241 - Operand should contain 1 column(s)
Update #1
select mytable.*
from mytable
where spam = 0
and deleted = 0
and draft = 0
and (subject like '%eli%' or body like '%eli%' or
(select users.firstname
from users where firstname like '%eli%') or
(select users.lastname
from users where lastname like '%eli%'))
and id_receiver = 24
order by id desc
Here the error:
(select CONCAT(users.firstname,' ', users.lastname) as fname,users.email
from users where firstname like '%guss%' or lastname like 'guss'))
In your subquery you can return only one column
This is the first column: CONCAT(users.firstname,' ', users.lastname) as fname
This is the second column: users.email
You put a 2-column result as an operand of OR expression.
This causes the issue. It should return one column or be compared to something.
But if you want to search in both tables I guess UNION would be something you need.
Though I think this is wrong I don't believe mytable.id relates to users.id but that's what a comment said...
SELECT Distinct mytable.*
FROM mytable
INNER JOIN users
on myTable.ID = users.Id
WHERE mytable.spam = 0
and mytable.deleted = 0
and mytable.draft = 0
and CONCAT_WS(mytable.subject, mytable.body, users.firstname, users.lastname) like '%eli%'
and mytable.id_receiver = 24
ORDER BY mytable.id desc
I removed the or using string concatenation. We want any record having the text of 'eli' in any of the columns subject, body, firstname, lastname. The system would have to loop through each column checking for a %eli% value. In theory up to 4 loops. By adding all the columns together to form one string and checking for eli we eliminate extra looping the engine would have to do at an overhead of the string concatenation. This should be faster.
I used distinct as I don't know what results you want and if the join will result in multiple records that serve no purpose. Since a * is being used I couldn't use a group by properly.
I joined to users assuming that you only want records in mytable that link to a user. This may be a wrong assumption.
I want to add some dynamic content in from clause based on one particular column value.
is it possible?
For Example,
SELECT BILL.BILL_NO AS BILLNO,
IF(BILL.PATIENT_ID IS NULL,"CUS.CUSTOMERNAME AS NAME","PAT.PATIENTNAME AS NAME")
FROM
BILL_PATIENT_BILL AS BILL
LEFT JOIN IF(BILL.PATIENT_ID IS NULL," RT_TICKET_CUSTOMER AS CUS ON BILL.CUSTOMER_ID=CUS.ID"," RT_TICKET_PATIENT AS PAT ON BILL.PATIENT_ID=PAT.ID")
But This query is not working.
Here
BILL_PATIENT_BILL table is a common table.
It can have either PATIENT_ID or CUSTOMER_ID. If a particular record has PATIENT_ID i want PATIENTNAME in RT_TICKET_PATIENT as NAME OtherWise it will hold CUSTOMER_ID. If it is i want CUSTOMERNAME as NAME.
Here I m sure That BILL_PATIENT_BILL must have either PATIENT_ID or CUSTOMER_ID.
Can anyone help me?
You can also use IF() to select the right values instead of constructing your query from strings:
SELECT
BILL.BILL_NO AS BILLNO,
IF( BILL.PATIENT_ID IS NULL, cus.CUSTOMERNAME, pat.PATIENTNAME ) AS NAME
FROM
BILL_PATIENT_BILL AS BILL
LEFT JOIN RT_TICKET_CUSTOMER cus ON BILL.CUSTOMER_ID = cus.ID
LEFT JOIN RT_TICKET_PATIENT pat ON BILL.PATIENT_ID = pat.ID
However, it would also be possible to PREPARE a statement from strings and EXECUTE it but this technique is prone to SQL injections, i can only disadvise to do so:
read here: Is it possible to execute a string in MySQL?