Cross Group By and Max Date Script - sql

I'm writing a script to pull a Group By and a MAX(CreatedOnDate) from two different tables but only return where table1's MAX(CreatedOnDate) is greater than table2's MAX(CreatedOnDate).
For example;
select MasterId, max(createdon) --Master id + latest product generated date
from product
group by MasterId
select contactId, max(createdon) --Contact id + latest edit date for that contact
from contactEdit
group by contactId
from contactEdit ce
join contactmaster cm
on ce.contactId = cm.contactid
join product p
on p.MasterId = cm.MasterId
Between these two tables there is a contactMaster table, the join of which is above also. I want to find a list of all Contacts who have had Edits made since the last Product was created relating to that Contact.
Something like;
where max(ce.createdon) > max(p.createdon)

i am not quite sure what your tables look like and what exactly you are trying to achieve, so this is a bit of a guess.
what you want to do is group the tables in subselects and then compare the maxdates:
with ce as (
select MasterId, max(createdon) maxco --Master id + latest product generated date
from product
group by MasterId
)
, prod as (
select contactId, max(createdon) maxco --Contact id + latest edit date for that contact
from contactEdit
group by contactId
)
, cm as (
select contactId, masterId, max(createdon) maxco --Master id + latest product generated date
from contactmaster
group by contactId, masterId
)
select contactId
from ce
join cm
on ce.contactId = cm.contactid
join product p
on p.MasterId = cm.MasterId
where ce.maxco > prod.maxco

Related

Select columns with multiple purcahses in a given date

table structure
I need to get names (FIO) of all the people that purchased product a and product b in any given day (but must be 2 purchases in a day) in april, or any other specified month.
What I tried to do is
with
purchased_items as
(
select customer_key
from purchase p
join product pr
on p.product_key = pr.product_key
where pr.name in ('Teddy bear', 'LEGO')
AND p.date_sold BETWEEN '01.04.2019' AND '30.04.2019'
group by customer_key
having count(distinct p.product_key) = 2
)
select *
from customer c
where exists (
select *
from purchased_items pui
where c.customer_key = pui.customer_key
);
But that only gives clients that bought 2 items in a month (not a single day).
I also suspect that it can be done by querying for Date, Client_name (FIO), array_agg(product.Name /*group by date */ ) , but I am not sure how to implemet it.
Thank you in advance for any help !
EDIT: figured it out.
with a as (
SELECT c.FIO, p.date_sold, pr.Name
FROM customer c
JOIN purchase p ON c.customer_key = p.customer_key
JOIN product pr ON p.product_key = pr.product_key
Where p.date_sold BETWEEN '01.04.2019' AND '30.04.2019' and (pr.name like '%LEGO%' OR pr.name like '%Teddy bear%') ),
count_name as (
select fio, count(distinct Name) as count, date_sold
from a
group by date_sold, fio)
select DISTINCT FIO
from count_name
where count=2
Although it's probably very subotimal

Get Most recent date from 2 tables and 2 persons

I have tables:
Person
-------------
ID | name
Notes
---------------------------
targetID | Content | Date
CallHistory
--------------------------
CallerID | CalleeID | Date
Now say I have a Person and a Spouse (which is on the same Person table).
They have corresponding notes and callhistory.
What I want is to Select the most recent date from either the spouse or person's most recent date (call or note)
Ive tried:
SELECT top 1 Date, ID from (select TargetID as ID, Date from notes
union
SELECT CalleeID as ID, Date from Callhistory)
WHERE ID in (person.ID, spouse.ID)
but without luck.
EDIT: This select is inside a select statement:
select p.*, SELECT top 1 Date, ID from (select TargetID as ID, Date from notes
union
SELECT CalleeID as ID, Date from Callhistory)
WHERE ID in (person.ID, spouse.ID) as RecentContactDate
From Person person
LEFT JOIN PersonRelationship pr on person.ID = pr.ID AND pr.Type = 3 -- spouse
LEFT JOIN Person spouse on pr.RelatedID = spouse.ID
......
Im getting Ambigous column name Date error.
any ideas?
#Sven's answer on this post has helped me solve my problem: SQL MAX of multiple columns?
What I've done is join the two tables from the two persons into a single row (need to get the MAX dates for each person's tables - CallHistory and Notes). Then get the MAX out of that four columns. So here's the fix:
select p.*,
(SELECT Max(v)
FROM (VALUES (pNote.Date), (pCh.Date), (sNote.Date),(sCh.Date)) AS value(v)) as [MaxDate]
WHERE ID in (person.ID, spouse.ID) as RecentContactDate
From Person person
LEFT JOIN PersonRelationship pr on person.ID = pr.ID AND pr.Type = 3 -- spouse
LEFT JOIN Person spouse on pr.RelatedID = spouse.ID
LEFT JOIN (SELECT ID, MAX(Date) from Notes) pNote on pNote.targetID = person.ID
LEFT JOIN (SELECT ID, MAX(Date) from CallHistory) pCh on person.ID = ch.CalleeID
LEFT JOIN (SELECT ID, MAX(Date) from Notes) sNote on spouse.ID = pNote.targetID
LEFT JOIN (SELECT ID, MAX(Date) from CallHistory) sCh on spouse.ID = ch.CalleeID
I hope this will help anyone in the future.

SQL - Select highest value when data across 3 tables

I have 3 tables:
Person (with a column PersonKey)
Telephone (with columns Tel_NumberKey, Tel_Number, Tel_NumberType e.g. 1=home, 2=mobile)
xref_Person+Telephone (columns PersonKey, Tel_NumberKey, CreatedDate, ModifiedDate)
I'm looking to get the most recent (e.g. the highest Tel_NumberKey) from the xref_Person+Telephone for each Person and use that Tel_NumberKey to get the actual Tel_Number from the Telephone table.
The problem I am having is that I keep getting duplicates for the same Tel_NumberKey. I also need to be sure I get both the home and mobile from the Telephone table, which I've been looking to do via 2 individual joins for each Tel_NumberType - again getting duplicates.
Been trying the following but to no avail:
-- For HOME
SELECT
p.PersonKey, pn.Phone_Number, pn.Tel_NumberKey
FROM
Persons AS p
INNER JOIN
xref_Person+Telephone AS x ON p.PersonKey = x.PersonKey
INNER JOIN
Telephone AS pn ON x.Tel_NumberKey = pn.Tel_NumberKey
WHERE
pn.Tel_NumberType = 1 -- e.g. Home phone number
AND pn.Tel_NumberKey = (SELECT MAX(pn1.Tel_NumberKey) AS Tel_NumberKey
FROM Person AS p1
INNER JOIN xref_Person+Telephone AS x1 ON p1.PersonKey = x1.PersonKey
INNER JOIN Telephone AS pn1 ON x1.Tel_NumberKey = pn1.Tel_NumberKey
WHERE pn1.Tel_NumberType = 1
AND p1.PersonKey = p.PersonKey
AND pn1.Tel_Number = pn.Tel_Number)
ORDER BY
p.PersonKey
And have been looking over the following links but again keep getting duplicates.
SQL select max(date) and corresponding value
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
SQL Server: SELECT only the rows with MAX(DATE)
Am sure this must be possible but been at this a couple of days and can't believe its that difficult to get the most recent / highest value when referencing 3 tables. Any help greatly appreciated.
select *
from
( SELECT p.PersonKey, pn.Phone_Number, pn.Tel_NumberKey
, row_number() over (partition by p.PersonKey, pn.Phone_Number order by pn.Tel_NumberKey desc) rn
FROM
Persons AS p
INNER JOIN
xref_Person+Telephone AS x ON p.PersonKey = x.PersonKey
INNER JOIN
Telephone AS pn ON x.Tel_NumberKey = pn.Tel_NumberKey
WHERE
pn.Tel_NumberType = 1
) tt
where tt.rn = 1
ORDER BY
tt.PersonKey
you have to use max() function and then you have to order by rownum in descending order like.
select f.empno
from(select max(empno) empno from emp e
group by rownum)f
order by rownum desc
It will give you all employees having highest employee number to lowest employee number. Now implement it with your case then let me know.

take each maximum value of a column and get information from another table

i have two tables:
create table saller(
id_saller int IDENTITY PRIMARY KEY,
name varchar(50),
branch varchar(10)
);
create table sale(
id_sale int IDENTITY PRIMARY KEY,
amount float,
id_saller int,
CONSTRAINT fk_saller FOREIGN KEY (id_saller)REFERENCES saller(id_saller)
);
i wanna get the biggest selling value of the amount for each branch
and get the name and id of the saller in charge for the biggest selling
i tried this:
SELECT saller.name, saller.id_saller,maxv.branch, maxv.maxbranch
FROM saller
INNER JOIN sale
ON saller.id_saller = sale.id_saller
INNER JOIN (
SELECT saller.branch,saller.id_saller,MAX(sale.amount) AS maxbranch
FROM saller
INNER JOIN sale
ON saller.id_saller = sale.id_saller
GROUP BY saller.branch,saller.id_saller
) AS maxv ON(sale.id_saller = maxv.id_saller)
One way to do it if you want to return exactly one row per branch even if you have ties
SELECT branch, id_saller, name, amount
FROM
(
SELECT r.branch, s.id_saller, r.name, s.amount,
ROW_NUMBER() OVER (PARTITION BY r.branch ORDER BY s.amount DESC) rnum
FROM sale s JOIN saller r
ON s.id_saller = r.id_saller
) q
WHERE q.rnum = 1
or if you want the highest value with ties
SELECT branch, id_saller, name, amount
FROM
(
SELECT r.branch, s.id_saller, r.name, s.amount,
RANK() OVER (PARTITION BY r.branch ORDER BY s.amount DESC) rank
FROM sale s JOIN saller r
ON s.id_saller = r.id_saller
) q
WHERE q.rank = 1
Here is SQLFiddle demo
According to your question, I don't understand the presence of branch, maybe a table that has not been mentionned. But to retrieve the seller id and name, you can try this;
SELECT saller.name, saller.id_saller
FROM saller
INNER JOIN sale
ON saller.id_saller = sale.id_saller
WHERE sale.Amount = (Select Max(Amount) from sale)

Find the latest date of two tables with matching primary keys

I have two tables tables, each with primary keys for different people and the contact dates in each category.I am trying to find the most recent contact date for each person, regardless of what table its in. For example:
CustomerService columns: CustomerKey, DateContacted
CustomerOutreach columns: CustomerKey, DateContacted
And I'm just trying to find the very latest date for each person.
Use something like this.
You need to combine the two tables. You can do this by a union. There will be duplicates, but you just group by the customerKey and then find the Max DateContacted
SELECT * INTO #TEMP FROM (
SELECT
CustomerKey
, DateContacted
FROM CustomerService CS
UNION
SELECT
CustomerKey
, DateContacted
FROM CustomerOutreach CS
)
SELECT
CustomerKey
, MAX(DateContacted)
FROM #TEMP
GROUP BY
CustomerKey
Join your tables on primary keys and make a conditional projection.
Select cs.CustomerKey,
CASE WHEN cs.DateContacted <= co.DateContacted
THEN co.DateContacted
ELSE cs.DateContacted END
from CustomerService cs inner join CustomerOutreach co
on cs.CustomerKey = co.CustomerKey
I would do something like this.
Select b.customerKey, b.dateContacted
from (
select a.customerKey, a.DateContacted, Row_Number() over (Partition by customerKey order by DateContacted desc) as RN
from (
Select c.customerKey,
case when (s.DateContacted > o.dateContacted) then s.dateContacted else o.datecontacted end as DateContacted
from Customer c
left outer join customerService s on c.customerKey = s.customerKey
left outer join customerOutreach o on c.customerKey = s.customerKey
where s.customerKey is not null or o.customerKey is not null
)a
)b
where b.RN = 1
This solution should take care of preventing the case of having duplicates if both tables have the same max DateContacted.
http://sqlfiddle.com/#!3/ca968/1