Select minimum time for the same id from two tables (MySQL) - mysql

Hi I have two tables and for the same contact "email" in the two tables, I want to know the first time the "email" gets in touch.
conversation_and_id
contact
Expected output
So far I only have done outer join to join the two tables, but it removed duplicated "email", which I need it to compare time difference from the same "email".
ALTER TABLE conversation_and_id CHANGE `email` `conversation_and_id_email` VARCHAR(100);
create table conversation_and_id_and_contact
SELECT *
FROM contact AS con
LEFT JOIN conversation_and_id AS ci ON con.email = ci.conversation_and_id_email
UNION
SELECT *
FROM contact AS con
RIGHT JOIN conversation_and_id AS ci ON con.email = ci.conversation_and_id_email;
create table final
select
if (f.email is not null, f.email, f.conversation_and_id_email) as email1,
if (f.atlas_interest is not null, f.atlas_interest, f.created_at) as time1,
if (f.conversation_and_id_email is not null, f.conversation_and_id_email, f.email) as email2,
if (f.created_at is not null, f.created_at, f.atlas_interest) as time2
from conversation_and_id_and_contact f;

The standard solution everywhere is to perform a full outer join with both tables and get the MIN() timestamp.
However, since MySQL does not (yet) support full outer joins you'll need to union a left and right joins to get the result you want. The final [unnecessarily long] query looks like:
select
coalesce(iemail, cemail) as email,
least(created_at, atlas_interest) as expressed_interest_at
from (
select -- this is the left join
i.email as iemail, i.created_at, c.email as cemail, c.atlas_interest
from conversation_and_id i
left join contact c on c.email = i.email
union
select -- this is the right join
i.email as iemail, i.created_at, c.email as cemail, c.atlas_interest
from conversation_and_id i
right join contact c on c.email = i.email
) x

Related

Selecting multiple rows in same table in the same JOIN

In the picture is my table situation right now:
The central table in this case right now is tblJob, here is everything defined what I need (not all in the picture).
The address table needs to return 2 values (1 of the company and 1 of the job itself). The only thing I need to do right now is to add the company address (the job address is already in my query) My query already looks like this:
SELECT
tblJob.jobID,
tblJob.amount AS jobAmount,
tblJob.extraInfo AS jobExtraInfo,
tblJob.views AS jobViews,
tblJob.description AS jobDescription,
tblJob.dateCreated AS jobDateCreated,
tblJobFunction.jobFunctionID,
tblJobFunction.jobFunction,
tblAddress.zipcode AS jobAddress,
tblAddress.city AS jobCity,
tblAddress.street AS jobStreet,
tblAddress.number AS jobNumber,
tblAddress.bus AS jobBus,
tblCountry.countryID AS jobCountryID,
tblCountry.country AS jobCountry,
tblCountry.areaCode AS jobAreaCode,
tblCompany.companyID,
tblCompany.name,
tblCompany.email,
tblCompany.GSM,
tblCompany.phoneNumber,
tblCompany.photoURL AS companyPhotoURL,
tblCompany.VATNumber,
tblCompany.websiteURL,
tblEvent.eventID,
tblEvent.event,
tblEvent.description AS eventDescription,
tblEvent.startDate AS eventStartDate,
tblEvent.endDate AS eventEndDate,
tblEvent.facebookURL,
tblEvent.photoURL AS eventPhotoURL,
tblEvent.views AS eventViews,
tblEvent.dateCreated AS eventDateCreated
FROM tblJob
JOIN tblAddress ON tblAddress.addressID = tblJob.addressID
JOIN tblCountry ON tblAddress.countryID = tblCountry.countryID
JOIN tblJobFunction ON tblJob.jobFunctionID =
tblJobFunction.jobFunctionID
JOIN tblCompany ON tblJob.companyID = tblCompany.companyID
LEFT JOIN tblEvent ON tblJob.eventID = tblEvent.eventID
Now the question is: how can I add the address from the company in the same query?
Use the address table as many times as you need it, but each time you must give it a new alias:
FROM tblJob
JOIN tblAddress ON tblAddress.addressID = tblJob.addressID
JOIN tblCountry ON tblAddress.countryID = tblCountry.countryID
JOIN tblJobFunction ON tblJob.jobFunctionID = tblJobFunction.jobFunctionID
JOIN tblCompany ON tblJob.companyID = tblCompany.companyID
JOIN tblAddress a2 ON a2.addressID = tblCompany.addressID
LEFT JOIN tblEvent ON tblJob.eventID = tblEvent.eventID
perhaps more like this:
SELECT JobAddress.street, CompanyAddress.street
FROM tblJob
JOIN tblAddress JobAddress ON JobAddress.addressID = tblJob.addressID
JOIN tblCompany ON tblJob.companyID = tblCompany.companyID
JOIN tblAddress CompanyAddress ON CompanyAddress.addressID = tblCompany.addressID

How to implement the below query using ssis

Can we discuss how to load the below query result into a destination table ,using ssis.I know we can use this in T-sql and also as an OLEDB source query.But still wondering how to implement it ,only using data flow components
SELECT
CLIENTID = CAST(PER.CLIENTID AS INT)
,CASEID = CAST(CS.CASEID AS INT)
,CAST(RIGHT(ev.oid, 10) as int) AS EventID
,ev.ServiceSubtypeCode
,ev.ServiceSubtypeCode +' - '+ev.ServiceSubTypeDesc as ServiceSubTypeDesc
,WU.ProviderID as WorkunitProviderID
,WU.ProviderName as WorkUnitProviderName
,ev.eventstartdate as AssessmentStartDate
,CONVERT(CHAR(5),ASM.getstarttimestamp,8) as AssessmentStartTime
,ev.EVENTENDDATE as AssessmentEndDate
,ev.EVENTENDTIME as AssessmentEndTime
,CAST(asm.getAssmtTemplateName as nvarchar(200)) as AssessmentTypeDesc
,j.providerid
,j.ProviderName
,j.ProviderRole
,EV.ISCOMPLETED
, EV.ISFINALISED
,EV.ISREVOKED
, EV.REVOKEDDATE AS REVOKEDDATE
,ASM.OID AS ASSESSMENTID
FROM DBO.ASSESSMENT ASM
LEFT OUTER JOIN DBO.INDIVIDUALPERSON PER ON ASM.MYPERSON = PER.OID
LEFT OUTER JOIN DBO.[CASE] CS ON ASM.MYCASE = CS.OID
LEFT OUTER JOIN (
SELECT CAST(ST.CODE AS VARCHAR(8))AS SERVICETYPECODE
, CAST(ST.DESCRIPTION AS VARCHAR(100)) AS SERVICETYPEDESC
, CAST(SST.CODE AS VARCHAR(8)) AS SERVICESUBTYPECODE
, CAST(SST.DESCRIPTION AS VARCHAR(100)) AS SERVICESUBTYPEDESC
, DATEADD(DD,0, DATEDIFF(DD,0,EV.GETRPSSTARTTIMESTAMP)) AS EVENTSTARTDATE
, CONVERT(CHAR(5),EV.GETRPSSTARTTIMESTAMP,8) AS EVENTSTARTTIME
, DATEADD(DD,0, DATEDIFF(DD,0,EV.GETRPSENDTIMESTAMP)) AS EVENTENDDATE
, CONVERT(CHAR(5),EV.GETRPSENDTIMESTAMP,8) AS EVENTENDTIME
,CAST(VEN.DESCRIPTION AS VARCHAR(12)) AS EVENTVENUE
,EV.ISCOMPLETED
, EV.ISFINALISED
,EV.ISREVOKED
, DATEADD(DD,0, DATEDIFF(DD,0,EV.REVOKEDON)) AS REVOKEDDATE
, EV.OID
from Event ev
LEFT OUTER JOIN ServiceType AS st ON ev.myServiceType = st.oid
LEFT OUTER JOIN ServiceSubtype AS sst ON ev.myServiceSubtype = sst.oid
LEFT OUTER JOIN AllCodes AS ven ON ev.myEventVenueCode = ven.oid
)as EV
ON ASM.MYEVENT = EV.OID
LEFT OUTER JOIN (
select wu.oid
,CAST(wu.providerid AS VARCHAR(100)) AS providerid
,CAST(nm.getfullname AS VARCHAR(100)) AS ProviderName
,wu.contactname
,wu.activatedate as StartDate
,wu.deactivatedate as EndDate
,case when wu.deactivatedate is null then 1 else 0 end as IsActiveToday
from workunitprovider wu
LEFT OUTER JOIN dbo.allprovidernames nm ON wu.oid = nm.myprovider
where nm.myNameType in (02245.0000000252)
) as WU
ON ASM.MYWORKUNITPROVIDER = WU.OID
Left join (
select f.myEvent
,f.myProvider
,f.myproviderrolecode
,f.Max_ProvOid
,CAST(g.providerid AS VARCHAR(100)) AS providerid
,CAST( i.description AS VARCHAR(150)) AS ProviderRole
,cast (h.getFullName as nvarchar (150)) as ProviderName
from( select d.myEvent
,myProvider
,myproviderrolecode
,d.Max_ProvOid
from ( select A.myEvent, max(b.oid) as Max_ProvOid
from alleventitems a
left outer join ProviderEventItemRole as b on a.oid = b.myeventitem
group by A.myEvent
) as d
left join
( select A.myEvent,b.myProvider,b.myproviderrolecode,a.oid as a_oid,b.oid as b_oid
from alleventitems a
left outer join ProviderEventItemRole as b on a.oid = b.myeventitem
)as e on d.myevent = e.myevent and max_provOid = b_oid
) as f
left join dbo.allproviders as g on f.myProvider = g.oid
left join (
select *
from dbo.AllProviderNames
where mynametype ='02245.0000000252'
)as h on f.myprovider =h.myprovider
left join dbo.allcodes as i on f.myproviderrolecode = i.oid
)as j on ASM.myevent = j.myevent;
Before we begin, a disclaimer:
Complex SELECT queries are best expressed in T-SQL. SSIS is best used for ETL tasks.
Now... with that out of the way. Let's see what we have. That query has fifteen LEFT JOINS nested across three levels: Five at the top, seven at the middle, and two at the bottom. Peppered throughout are a some CAST()s and GROUP BYs. All of those SQL commands can be done with SSIS components.
JOIN = Merge Join component.
GROUP BY = Aggregate component.
CAST = Derived Column component.
Since you have such a large query, I'd recommend breaking this into smaller chunks. Starting with the inner most join.
select
d.myEvent
,myProvider
,myproviderrolecode
,d.Max_ProvOid
from (
select A.myEvent, max(b.oid) as Max_ProvOid
from alleventitems a
left outer join ProviderEventItemRole as b
on a.oid = b.myeventitem
group by A.myEvent
) as d
left join (
select A.myEvent,b.myProvider,b.myproviderrolecode,a.oid as a_oid,b.oid as b_oid
from alleventitems a
left outer join ProviderEventItemRole as b
on a.oid = b.myeventitem
) as e
Translating that to SSIS would look like this.
Above, we're merging four tables into one. You can learn more about how to configure Merge Joins here. Repeat the above pattern for the remaining JOINS and connect them all together and you will have translated the entire query to SSIS!
Now that we can see how it may be done, may I ask why we'd want to do this in SSIS?

How to select all records from a table by replacing values for two fields from other tables?

This is the table design of an application I need to build. Kindly ignore the Role Table in the image.
Is there any method by which I can select all the records in the table transfer log , but instead of showing "User No" and "Plant No" in the result , I need to show the corresponding Employee No/Username from the user table and corresponding Plant Id from Plant Table.
Try this;)
select distinct
log.LogNo, u.EmployeeNo/Username, p.PlantId, log.StartDate, log.EndDate, log.Active
from TransferLog log
left join UserTable u on u.UserNo = log.UserNo
left join PlantTable p on p.PlantNo = log.PlantNo
Use inner join
select a.*, b.username, c.pantname
from transfer_log as a
inner join User as b a.userno = b.userno
inner join plant as c a.plantno = c.plantno

Inner Join from multiple tables

I have 3 tables, as follows:
Patron
======
patron_num
Booking_For_Schedule
====================
tname
date
time
booking_num
Booking_By_Patron
=================
booking_num
patron_num
I would like to retrieve a result with columns patron_num, date, time, and tname, like so:
patron_num date time tname
1 2013-11-03 20:00 TestName
...etc
The purpose of this homework question is to teach us INNER JOINS, but I am having some difficulty. Could some kind SO user push me in the right direction?
Here's my SQL:
SELECT `patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`
which returns the error: #1052 - Column 'patron_num' in field list is ambiguous
SELECT `P`.`patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`
Will help with the ambiguity.
Since patron_num is in multiple tables you need to specify which one you want to use. You can do this by adding the table alias before it like you are in your joins. Example:
SELECT `B`.`patron_num`,`date`,`time`,`tname`
FROM `booking_for_schedule` `F`
INNER JOIN `booking_by_patron` `B` on `F`.`booking_num` = `B`.`booking_num`
INNER JOIN `patron` `P` on `B`.`patron_num`=`P`.`patron_num`

Replace Default Null Values Returned From Left Outer Join

I have a Microsoft SQL Server 2008 query that returns data from three tables using a left outer join. Many times, there is no data in the second and third tables and so I get a null which I think is the default for left outer join. Is there a way to replace the default values in the select statement? I have a workaround in that I can select into a table variable but it feels a little dirty.
SELECT iar.Description, iai.Quantity, iai.Quantity * rpl.RegularPrice as 'Retail',
iar.Compliance FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
I would like the Quantity and RegularPrice to default to zero if possible.
That's as easy as
IsNull(FieldName, 0)
Or more completely:
SELECT iar.Description,
ISNULL(iai.Quantity,0) as Quantity,
ISNULL(iai.Quantity * rpl.RegularPrice,0) as 'Retail',
iar.Compliance
FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
In case of MySQL or SQLite the correct keyword is IFNULL (not ISNULL).
SELECT iar.Description,
IFNULL(iai.Quantity,0) as Quantity,
IFNULL(iai.Quantity * rpl.RegularPrice,0) as 'Retail',
iar.Compliance
FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
MySQL
COALESCE(field, 'default')
For example:
SELECT
t.id,
COALESCE(d.field, 'default')
FROM
test t
LEFT JOIN
detail d ON t.id = d.item
Also, you can use multiple columns to check their NULL by COALESCE function.
For example:
mysql> SELECT COALESCE(NULL, 1, NULL);
-> 1
mysql> SELECT COALESCE(0, 1, NULL);
-> 0
mysql> SELECT COALESCE(NULL, NULL, NULL);
-> NULL
For Oracle you can use:
NVL(columnName,deafultValue) :- NVL is used to convert a null value to a default value in the query output. eg. If you want to replace null values with 'NA' then use something like this.
SELECT NVL(columnName,'NA') FROM tableName