When a new customer contacts us, they are allocated a reference number.
Unfortunately our contact centre sometimes logs the same person without checking if they have contacted us before and the customer ends up with two reference numbers. We want to cleanse this, so:
I would like to output instances where the customer's surname, address1 and zipcode are duplicated but only if the customer has different reference numbers.
This is the type of data that I'd like to see output:
Ref LastName Address 1 Zip
1875 Faulkner 10 Smith Street 08540
1876 Faulkner 10 Smith Street 08540
I have tried a few ideas, the latest being (forgive the huge amount of code here):
with Duplicates as
(
select r.LastName
, a.Address1
, a.ZipCode
, COUNT(*) as DuplicateCount
FROM Reference r
INNER JOIN Address a ON a.ReferenceNumber = r.ReferenceNumber
LEFT OUTER JOIN Telephone t ON r.ReferenceNumber = t.ReferenceNumber
LEFT OUTER Join Email e ON r.ReferenceNumber = e.ReferenceNumber
group by r.LastName
, a.Address1
, a.ZipCode
having COUNT(*) > 1
)
SELECT
r.ReferenceNumber
, r.LastName
, r.FirstName
,a.ReferenceNumber
, a.Address1
, a.Address2
, a.Address3
, a.Address4
, a.ZipCode
,t.ReferenceNumber
, t.TelephoneNumber
,e.ReferenceNumber
, e.EmailAddress
, d.DuplicateCount
FROM Reference r
INNER JOIN Address a ON a.ReferenceNumber = r.ReferenceNumber
LEFT OUTER JOIN Telephone t ON r.ReferenceNumber = t.ReferenceNumber
LEFT OUTER Join Email e ON r.ReferenceNumber = e.ReferenceNumber
join Duplicates d on d.LastName = r.LastName
AND d.Address1 = a.Address1
AND d.ZipCode = a.ZipCode;
Unfortunately this returns all duplicates, not those with the same surname, address1 and zipcode and different reference numbers.
Do you have any advice on how I can achieve this?
Many thanks.
Try using this part of your code in a self join by putting the data into a table variable or using aliases.
SELECT
r.ReferenceNumber
, r.LastName
, r.FirstName
,a.ReferenceNumber
, a.Address1
, a.Address2
, a.Address3
, a.Address4
, a.ZipCode
,t.ReferenceNumber
, t.TelephoneNumber
,e.ReferenceNumber
, e.EmailAddress
, d.DuplicateCount
FROM Reference r
INNER JOIN Address a ON a.ReferenceNumber = r.ReferenceNumber
LEFT OUTER JOIN Telephone t ON r.ReferenceNumber = t.ReferenceNumber
LEFT OUTER Join Email e ON r.ReferenceNumber = e.ReferenceNumber
An example of self join is here.
Related
I have a query where I am getting child emails for a parent email after few joins
select * from user_email WHERE user_eaddr_txt in (select u.ADDR_TEXT from cust_mail c, intnl_user u where c.cust_id=u.cust_id and c.cust_eaddr_txt in ('TEST#GMAIL.COM')) ;
I get all child emails linked to that parent email.
testchild#gmail.com
Is there anyway I can get Parent email along with child email in the result set?
testchild#gmail.com TEST#GMAIL.COM
What about something like this
SELECT c.cust_eaddr_txt as parent_email
, u.ADDR_TEXT as child_email
FROM cust_mail c
INNER JOIN intnl_user u ON c.cust_id=u.cust_id
WHERE c.cust_eaddr_txt = 'TEST#GMAIL.COM'
if you need additional details from the user_email table you need to join that as well
SELECT c.cust_eaddr_txt as parent_email
, u.ADDR_TEXT as child_email
, ue.*
FROM cust_mail c
INNER JOIN intnl_user u ON c.cust_id=u.cust_id
INNER JOIN user_email ue ON ue.user_eaddr_txt = u.ADDR_TEXT
WHERE c.cust_eaddr_txt = 'TEST#GMAIL.COM'
I assumed an inner join but depending on your model and needs it could be a left join as well.
I need your help. I need an advanced Query to my database. Im showing part of my database following:
Place (id, name, address)
Local (id, place_id, name)
PlaceReservation(id, local_id, date)
Media_Place (id, place_id, type)
Now I need a query, which gets all places with logo, which have AT LEAST ONE local which hasn't been reserved on a specific day e.g: 2015-07-01.
Help me please, because I haven't an idea how to do it. I thought about an outer join but I don't know how use it.
I was trying by:
$query = 'SELECT DISTINC *,
(SELECT sum(po.rating)/count(po.id)
FROM "Place_Opinion" po
WHERE po.place_id = p.id AND po.deleted = false) AS rating,
mp.path as logo_path
FROM "Place" p
INNER JOIN "Media_Place" mp ON mp.place_id = p.id
JOIN Local ON Local.place_id = Place.id
LEFT JOIN (
SELECT id AS rr, local_id
FROM PlaceReservation
WHERE date_start = \'2015-07-01\') Reserved ON Reserved.local_id = Local.id
WHERE mp.type = ' . Model_Row_MediaPlace::LOGO_TYPE . '
AND mp.deleted = false
AND p.deleted = false
AND rr IS NULL';
Looking for things that do not exist in a database is usually very inefficient. But you can change the logic around by finding places that do have a booking for the specified date, then LEFT JOIN that to all places with a logo and filter out the records with a reservation:
SELECT DISTINCT p.*, po.rating, mp.path as logo_path
FROM "Place" p
JOIN "Media_Place" mp ON mp.place_id = p.id AND mp.deleted = false AND mp.type = ?
JOIN Local ON Local.place_id = p.id
LEFT JOIN (
SELECT id AS rr, local_id
FROM PlaceReservation
WHERE date_start = '2015-07-01') reserved ON reserved.local_id = Local.id
LEFT JOIN (
SELECT place_id, avg(rating) AS rating
FROM "Place_Opinion"
WHERE deleted = false
GROUP BY place_id) po ON po.place_id = p.id
WHERE p.deleted = false
AND reserved.rr IS NULL;
The average rating per places is calculated in a separate sub-query. The error you had was because you referenced the "Place" table (p.id) before it was defined. For simple columns you can do that, but for sub-queries you can't.
I am getting error Sub Query Returns more than 1 value
here is my Query
SELECT d.Description ,s.Version , d.UtiPrefix , d.UTI , d.PrimaryAC , s.ReportingObb , s.ReportingObb , d.LEI , d.LEI_Countp , d.LEI , s.ReportingDeleg ,d.Curr , c.Trade_Party_Domicile ,c.LEI_SGR
, Price =( select Price
From Price
inner join Derivatives
on Derivatives.UTI = Price.UTI)
FROM Derivatives as d
INNER JOIN Settings as s
ON d.LEI_SGR = s.LEI_SGR
INNER JOIN Clients c
ON d.LEI_SGR = c.LEI_SGR
Use a correlated subquery
Price =( select Price From Price p WHERE d.UTI = p.UTI)
I suspect this returns more than one row
( select Price
From Price
inner join Derivatives
on Derivatives.UTI = Price.UTI )
why are you mixing sub queries with joins?
SELECT d.Description ,s.Version , d.UtiPrefix , d.UTI , d.PrimaryAC , s.ReportingObb
, s.ReportingObb , d.LEI , d.LEI_Countp , d.LEI , s.ReportingDeleg ,d.Curr
, c.Trade_Party_Domicile ,c.LEI_SGR
, p.Price
FROM Derivatives as d
INNER JOIN Settings as s
ON d.LEI_SGR = s.LEI_SGR
INNER JOIN Clients c
ON d.LEI_SGR = c.LEI_SGR
INNER JOIN Price p
ON p.UTI = d.UTI
I am using Moodle LMS and I need to run a report to find out how long it takes between the time a student submits any sort of human-gradable assignment and the time it is graded so that we can monitor our staff's efficiency. Right now I am going for a query similar to the one below. I still need to add in the actual assignments but I am not sure which items in moodle could possibly fit into the "submitted but waiting to be graded" category.
Which tables am I missing for this query and is there anything I am obviously doing wrong here?
SELECT c.shortname AS course_name
, cm.id AS cmid
, cm.course AS courseid
, md.name AS modname
, gi.itemname AS itemname
, u.firstname AS student_first
, u.lastname AS student_last
, f.firstname AS grader_first
, f.lastname AS grader_last
, NULLIF(GREATEST(IFNULL(g.overridden, 0)
,IFNULL(g.timecreated, 0)
,IFNULL(g.timemodified, 0))
,0) AS graded_unixtimestamp
FROM mdl_user u
JOIN mdl_user_enrolments ue
ON (u.id = ue.userid)
JOIN mdl_enrol e
ON (e.id = ue.enrolid)
JOIN mdl_course c
ON (c.id = e.courseid)
JOIN mdl_course_modules cm
ON (c.id = cm.course)
JOIN mdl_modules md
ON (md.id = cm.module)
JOIN mdl_grade_items gi
ON (
gi.itemmodule = md.name
AND gi.iteminstance = cm.instance
AND gi.courseid = cm.course)
LEFT
JOIN mdl_grade_grades g
ON (gi.id = g.itemid AND g.userid = u.id)
LEFT
JOIN mdl_user f
ON (g.usermodified = u.id);
here`s my query
SELECT cont.FILTER_VALUE as filter,
o.[OBJECT_ID] as Id, o.[OBJECT_NAME] as Name, o.DESCRIPTION as Description, o.CREATED as Created,
o.MODIFIED as Modified, u.[LOGIN] as LastModifiedByLogin, o.[OBJECT_NAME] as ObjectName, t.[TEMPLATE_NAME] as TemplateName--,p.[PAGE_NAME] as PageName
FROM
[OBJECT] AS o
LEFT OUTER JOIN [CONTAINER] as cont
on cont.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [OBJECT_VALUES] AS ov ON
ov.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [PAGE] AS p ON o.[PAGE_ID] = p.[PAGE_ID]
INNER JOIN [USERS] as u on u.[USER_ID] = o.LAST_MODIFIED_BY INNER JOIN [PAGE_TEMPLATE] as t
on o.[PAGE_TEMPLATE_ID] = t.[PAGE_TEMPLATE_ID] INNER JOIN [site] as s on t.SITE_ID = s.SITE_ID
WHERE
s.SITE_ID = '34' --AND сont.[FILTER_VALUE] is null--like '%fff%'
And it works nice, until I remove the comment.
Here's a mess of joins, still it has sense. I inner join main table with couple of others, and left join with optional, so, that I have a column, that contains cont.FILTER_VALUE as filter, its null in some records, I can get it, but I cant filter by this field.
I get The multi-part identifier "сont.FILTER_VALUE" could not be bound.
I've looked through similar topics, but found no useful information. I don't use any old SQL dialects: everywhere I use INNER/LEFT joins, tried group by and order by, tried to re-order joins - nothing helped. I guess I just don't understand something important about joins, could you tell me, please.
Thanx.
if you wrote it like this:
s.SITE_ID = '34' AND сont.[FILTER_VALUE] is null like '%fff%'
its just wrong syntax. you're missing a column for the LIKE function (in which column does the query suppose to look for the pattern?). if you didnt write it like that, please post what you did write
I don't know why you're getting your error, but try this just in case, while we wait for a better answer:
SELECT FILTER_VALUE as filter
, o.[OBJECT_ID] as Id
, o.[OBJECT_NAME] as Name
, o.DESCRIPTION as Description
, o.CREATED as Created
, o.MODIFIED as Modified
, u.[LOGIN] as LastModifiedByLogin
, o.[OBJECT_NAME] as ObjectName
, t.[TEMPLATE_NAME] as TemplateName
FROM [OBJECT] AS o
INNER JOIN [USERS] as u
ON u.[USER_ID] = o.LAST_MODIFIED_BY
INNER JOIN [PAGE_TEMPLATE] as t
ON o.[PAGE_TEMPLATE_ID] = t.[PAGE_TEMPLATE_ID]
INNER JOIN [site] as s
ON t.SITE_ID = s.SITE_ID
LEFT JOIN [CONTAINER] as cont
ON cont.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [OBJECT_VALUES] AS ov
ON ov.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [PAGE] AS p
ON o.[PAGE_ID] = p.[PAGE_ID]
WHERE s.SITE_ID = '34' AND FILTER_VALUE IS NULL
Well, I solved this problem, using CTE, still I wonder, why did I have problems without cte.
This way it works good
with query_CTE
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY o.[OBJECT_ID] asc) as rowNum,
o.[OBJECT_ID] as Id, o.[OBJECT_NAME] as Name, o.DESCRIPTION as Description, o.CREATED as Created,
o.MODIFIED as Modified, u.[LOGIN] as LastModifiedByLogin, o.[OBJECT_NAME] as ObjectName, t.[TEMPLATE_NAME] as TemplateName,p.[PAGE_NAME] as PageName,
s.SITE_ID, t.PAGE_TEMPLATE_ID, p.PAGE_ID, ov.VARIABLE_NAME, ov.VARIABLE_VALUE, cont.FILTER_VALUE, cont.DYNAMIC_CONTENT_VARIABLE, cont.SELECT_START,
cont.SELECT_TOTAL
FROM [OBJECT] AS o
INNER JOIN [USERS] as u
ON u.[USER_ID] = o.LAST_MODIFIED_BY
INNER JOIN [PAGE_TEMPLATE] as t
ON o.[PAGE_TEMPLATE_ID] = t.[PAGE_TEMPLATE_ID]
INNER JOIN [site] as s
ON t.SITE_ID = s.SITE_ID
LEFT JOIN [CONTAINER] as cont
ON cont.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [OBJECT_VALUES] AS ov
ON ov.[OBJECT_ID] = o.[OBJECT_ID]
LEFT JOIN [PAGE] AS p
ON o.[PAGE_ID] = p.[PAGE_ID]
)
select rowNum,
Id, Name,[Description], Created, Modified, LastModifiedByLogin, ObjectName, TemplateName,PageName
from query_CTE