Here's what I'm trying to achieve :
Select a person's or firm's name depending on the contact type.
Tables :
CONTACTS : PEOPLE FIRMS
- id - contact_id - contact_id
- type (person/firm) - name - name
I would like this kind of magic :
SELECT type
FROM contacts
WHERE contacts.id = 42;
SELECT model.name
FROM contacts LEFT JOIN model ON model.contact_id = contacts.id
WHERE contacts_id = 42
AND model = CASE (WHEN type = "person" THEN "people"
WHEN type = "firm" THEN "Firms" END); (Not sure this one works)
All in one query. Thanks !
You could do like below, join two tables and then decide which column to use according to contacts.type.
SELECT
(CASE WHEN t1.type = 'person' THEN t2.name WHEN t1.type = 'firm' THEN t3.name) AS contact_name
FROM contacts t1
LEFT JOIN people t2 ON t1.id = t2.contact_id
LEFT JOIN firms t3 ON t1.id = t3.contact_id
Simply left join both tables; one of them will match id and type. Use COALESCE then to display the one name found.
select coalesce(p.name, f.name) as name
from contacts c
left join people p on p.contacts_id = c.id and c.type = 'person'
left join firms f on f.contacts_id = c.id and c.type = 'firm'
where c.id = 42;
You can use dynamic sql like this:
declare
#table_name nvarchar(20),
#query nvarchar(max)
SELECT
#table_name =
case type
when 'person' then 'people'
when 'firm' then 'firms'
end
FROM contacts
WHERE contacts.id = 42;
set #query = N'SELECT ' + #table_name + '.name ' +
'FROM contacts LEFT JOIN model ON ' + #table_name + '.contact_id = contacts.id
WHERE contacts_id = 42 '
exec sp_executesql #query
Here is an alternative way without a join:
select
case when c.type = 'person' then
(select name from people p where p.contacts_id = c.id)
else
(select name from firms f on f.contacts_id = c.id)
end as name
from contacts c
where c.id = 42;
You see, there are many ways to address the problem. Just pick the one you find most readable.
Related
Here is my code and result :
SELECT DISTINCT
CAL.CarListingId,
(SELECT
IF(REPLACE(carImage.ImageUrl,'~','') IS NULL,'asdf',REPLACE(carImage.ImageUrl,'~',''))
FROM
carImage
WHERE
IsMainImage = 1 AND Status = 1
AND CarListingId = CAL.CarListingId) AS ImageUrl,
CAL.ListingNumber,
CAL.Caption,
CAL.Year,
CAL.Km,
CAL.Color,
CAL.Price,
CONCAT((SELECT Name FROM City WHERE CityId IN (SELECT CityId FROM County WHERE CountyId = CAL.CountyId)),'/', (SELECT Name FROM County WHERE CountyId = CAL.CountyId)) AS Region,
CAL.Creation
FROM
carlisting AS CAL
INNER JOIN
User AS U ON U.UserId = CAL.CreatedBy
INNER JOIN
carlistingcategory AS CLC ON CLC.CarListingId = CAL.CarListingId
LEFT JOIN CarImage AS CI ON CI.CarListingId = CAL.CarListingId
ORDER BY CAL.Creation;
I use this query as a subquery in another query. I need to check this query's result if it is `NULL`. But as you can see there is no data so `IS NULL` returns false. How can I check the sub query has data ?
try this query:
SELECT DISTINCT
CAL.CarListingId,
CAL.ListingNumber,
CAL.Caption,
CAL.Year,
CAL.Km,
CAL.Color,
CAL.Price,
CONCAT((SELECT Name FROM City WHERE CityId IN (SELECT CityId FROM County WHERE CountyId = CAL.CountyId)),'/', (SELECT Name FROM County WHERE CountyId = CAL.CountyId)) AS Region,
CAL.Creation,
( case when CI.ImageUrl IS NULL then 'asdf' else CI.ImageUrl
end)
FROM
carlisting AS CAL
LEFT JOIN CarImage AS CI ON CI.CarListingId = CAL.CarListingId
INNER JOIN User AS U ON U.UserId = CAL.CreatedBy
INNER JOIN carlistingcategory AS CLC ON CLC.CarListingId = CAL.CarListingId
ORDER BY CAL.Creation;
I have this query:
SELECT Concat(f.name, ' ', f.parent_names) AS FullName,
stts.name AS 'Status',
u.name AS Unit,
city.name AS City,
(SELECT Group_concat(c.mobile1)
FROM contacts c
WHERE c.id = f.husband_id
OR c.id = f.wife_id) AS MobilePhones,
f.phone AS HomePhone,
f.contact_initiation_date AS InitDate,
f.status_change_date AS StatusChangeDate,
cmt.created_at AS CommentDate,
cmt.comment AS LastComment,
f.reconnection_date AS ReconnectionDate,
(SELECT Group_concat(t.name, ' ')
FROM taggings tgs
JOIN tags t
ON tgs.tag_id = t.id
WHERE tgs.taggable_type = 'family'
AND tgs.taggable_id = f.id) AS HandlingStatus
FROM families f
JOIN categories stts
ON f.family_status_cat_id = stts.id
JOIN units u
ON f.unit_id = u.id
JOIN categories city
ON f.main_city_cat_id = city.id
LEFT JOIN comments cmt
ON f.last_comment_id = cmt.id
WHERE 1 = 0
OR ( u.is_busy = 1 )
OR ( f.family_status_cat_id = 1423 )
OR ( f.family_status_cat_id = 1422
AND f.status_change_date BETWEEN '2011-03-21' AND '2012-03-13' )
My problem is very specific. It is regarding the line:
SELECT GROUP_CONCAT( c.mobile1 )
FROM contacts c
WHERE c.id = f.husband_id
OR c.id = f.wife_id
) AS MobilePhones
When I use EXPLAIN, it seems that this query is bad. I get for this table (c = contacts): 38307 rows.
On what columns should I put the index according to the query?
I tried mobile1 - but no improvement (BTW - family_id is indexed in the contacts table).
I attach the image of the explain result:
Or maybe someone can help me optimize the query...
Any column you'll be searching on, to speed up the process. Keep in mind that keys are already indexed.
Well, it seems that using the GROUP_CONCAT is the problem.
I just seperated the wife and husband mobile to be 2 different columns.
First, I thought that using the GROUP_CONCAT will be faster, but it proved to be VERY WRONG.
Just out of my curiosity, what is the performance of the query
SELECT GROUP_CONCAT( c.mobile1 )
FROM contacts c
WHERE c.id IN(f.husband_id, f.wife_id)
) AS MobilePhones
I am joining multiple tables into a single query. I need to do a partial match on values in an IN statement. Here is an example.
SELECT DISTINCT
am.id AS id,
am.flagged AS flagged,
am.name AS name,
am.type AS type,
am.file AS file,
am.s3_tag AS s3_tag,
am.low_s3_tag AS low_s3_tag
FROM accounts_media am
LEFT JOIN accounts_location_media alm ON am.id = alm.media_id
LEFT JOIN accounts_location al ON al.id = alm.location_id
LEFT JOIN accounts_person_media apm ON am.id = apm.media_id
LEFT JOIN accounts_person ap ON ap.id = apm.person_id
LEFT JOIN accounts_event_media_record aemr ON am.id=aemr.media_id
LEFT JOIN accounts_medianote_media_record amma ON am.id=amma.media_id
LEFT JOIN accounts_medianote amn ON amma.medianote_id=amn.id
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
AND ('Da' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
AND ('Rob' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
In the
AND ('Da' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
statement there are values that say 'Dan', 'Daniel', etc. in the table. There is also 'Rob' and 'Robert'. I need that statement to make sure and name that contains 'Da' AND any name that contains 'Rob' from that table. Is there a way to do this?
So a record can be linked to multiple people in the accounts_person table. So lets say I have three records.
Record One: A person named Dan is attached to the record.
Record Two: A person named Robert is attached to the record.
Record Three: A person named Dan and a person named Robert are attached to the record.
I want the query to only return Record Three because it has the match of 'Da' and 'Rob'.
Try this:
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
-- AND ( ap.first_name LIKE '%Da%' OR ap.first_name LIKE '%Rob%')
AND EXISTS
( SELECT 1
FROM accounts_person apx
WHERE apx.first_name LIKE '%Da%'
AND apx.account_id = am.account_id
)
AND EXISTS
( SELECT 1
FROM accounts_person apy
WHERE apy.first_name LIKE '%Rob%'
AND apy.account_id = am.account_id
)
I'm not sure, but I think you want a like statement, with a wild card after the Da.
SELECT DISTINCT
am.id AS id,
am.flagged AS flagged,
am.name AS name,
am.type AS type,
am.file AS file,
am.s3_tag AS s3_tag,
am.low_s3_tag AS low_s3_tag
FROM accounts_media am
LEFT JOIN accounts_location_media alm ON am.id = alm.media_id
LEFT JOIN accounts_location al ON al.id = alm.location_id
LEFT JOIN accounts_person_media apm ON am.id = apm.media_id
LEFT JOIN accounts_person ap ON ap.id = apm.person_id
LEFT JOIN accounts_event_media_record aemr ON am.id=aemr.media_id
LEFT JOIN accounts_medianote_media_record amma ON am.id=amma.media_id
LEFT JOIN accounts_medianote amn ON amma.medianote_id=amn.id
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
AND (accounts_person.first_name like '%Da%'
OR accounts_person.first_name like '%Rob%')
AND accounts_person.account_id = '1234'
I need to convert this sql query to linq to sql and the result returns a IEnumerable:
select VisualAidName, v.VisualAidID, vs.VisualAidStatusName,
br.BrandName, v.IsEnabled, v.VisualAidCode, v.DateApproved,
br.BrandID, type, UserFirstName+ ' ' + UserLastName as name, AreaID
from VisualAids v inner join VisualAidStatus vs
on v.VisualAidStatusId = vs.VisualAidStatusId
inner join brands br
on v.BrandID = br.BrandId
inner join VisualAids_Areas_Link vareas
on v.VisualAidID = vareas.VisualAidID
left join users us
on v.Owner = us.UserID
where
AreaID IN (
select areaid
from Users inner join Users_Area_Link
on Users.UserID = Users_Area_Link.UserID
where Users.UserID= 3
)
I did this:
IEnumerable<Visual_Aid> visualAll = from v in Context.VisualAids
join vs in Context.VisualAidStatus on v.VisualAidStatusId equals vs.VisualAidStatusId
join br in Context.Brands on v.BrandID equals br.BrandId
join us in Context.Users on v.Owner equals us.UserID into vadis
from x in vadis.DefaultIfEmpty()
select new Visual_Aid()
{
VisualAid_Name = v.VisualAidName,
VisualAid_Id = v.VisualAidID,
VisualAid_StatusName = vs.VisualAidStatusName,
VisualAid_BrandsName = br.BrandName,
VisualAid_IsEnabled = bool.Parse(v.IsEnabled.ToString()),
VisualAid_Code = v.VisualAidCode,
VisualAid_DateApp = v.DateApproved.ToString() ?? "",
VisualAid_BrandId = int.Parse(v.BrandID.ToString()),
VisualAid_Type = v.Type,
VisualAid_Owner = x.UserID == null ? "" : x.UserFirstName + " " + x.UserLastName
};
but I need to do the part of the subquery, ie, I need to include this:
where AreaID IN (
select areaid from Users inner join Users_Area_Link
on Users.UserID = Users_Area_Link.UserID where Users.UserID= 3
)
Anybody know how? thank you very much in advance
You can add this as a where statement:
.......
join us in Context.Users on v.Owner equals us.UserID into vadis
from x in vadis.DefaultIfEmpty()
where (
from user in Context.Users
join userArea in Users_Area_Link
on user.UserID equals userArea.UserID
where user.UserID==3
select userArea.areaid
).Contains(????.AreaID)
select new Visual_Aid()
{
.......
I have to write an SQL statement which contain a field that contain two different values consecutively but in the way I have wrote it, it return always null because it is interpreted as having the two value in the same time!
My conditions should be : (ci.field = 'Group' and ci.oldString = 'Triage' ) and (ci.field='assignee' and ci.newString is not NULL)
That means calculate time between: when the issue is assigned to group named Triage and when the issue is assigned to a person.
How can I fix it?
My SQL statement:
select TIMEDIFF(a.created,b.created)
from
(select g.created, g.issueid as groupid1
from changegroup g
join changeitem ci on (ci.groupid = g.id)
join jiraissue ji on (ji.id = g.issueid)
join project p on (p.id = ji.project)
join priority pr on (pr.id = ji.priority)
where ci.field = 'Group'
and ci.oldString = 'Triage'
and ci.field='assignee'
and ci.newString is not NULL
and p.pname = 'Test'
and pr.pname='P1'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) a
left join (
select ji.created, ji.id as groupid2
from jiraissue ji
join changegroup g on (g.issueid = ji.id)
join project p on (p.id = ji.project)
where p.pname = 'Test'
and ji.created between '2011-08-11 14:01:00' and '2011-08-12 14:11:00'
) b ON (a.groupid1 = b.groupid2);
This is the table from which I should retrieve data
See my comment about the quality of your question but a hint at how to solve this goes like (assuming you can make sure this doesn't create 1-n joins)
select groupid_orsomething_else, TIMEDIFF(a.created, b.created)
from yourtable
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'Group' and oldstring is 'Triage'
) a
on a.groupid_orsomething_else = yourtable.groupid_orsomething_else
left join
(select groupid_orsomething_else, created
from yourtable
where field = 'assignee' and oldstring is null) b
on b.groupid_orsomething_else = yourtable.groupid_orsomething_else