Trying to select records that are all for the same customer, but where the address is different.
So I can later let the user choose Bob Yonkers, then choose to update all of Bob's records to a specific address. So I want to show all the available records.
Data Example:
CUSTOMER_NAME, CUSTOMER_ADDRESS
Bob Yonkers , 42 Satellite Cir
Bob Yonkers , 667 Orbit St
Bob Yonkers , 42 Satellite Cir
Bob Yonkers , 667 Orbit St
David Boom , 5959 Bush Ave
David Boom , 5959 Bush Ave
David Boom , 5959 Bush Ave
David Boom , 5959 Bush Ave
David Boom , 5959 Bush Ave
Ruby Tuesday , 123 Highway Ln Apt#1
Ruby Tuesday , 123 Highway Ln
David Boom ,5959 Bush Ave
David Boom ,5959 Bush Ave
David Boom ,5959 Bush Ave
So the query would bring back these results...
Result Example:
CUSTOMER_NAME, CUSTOMER_ADDRESS
Bob Yonkers , 42 Satellite Cir
Bob Yonkers , 667 Orbit St
Ruby Tuesday , 123 Highway Ln Apt#1
Ruby Tuesday , 123 Highway Ln
Any help would be appreciated.
SELECT *
FROM [table] t1
INNER JOIN [table] t2 ON t1.Name=t2.Name AND t1.Address<>t2.Address
This is a refinement of Joel's:
SELECT distinct t1.*
FROM [table] t1
INNER JOIN [table] t2 ON t1.Name=t2.Name AND t1.Address<>t2.Address
give this a try...
select * from (select count(customername) as ct, customername, address from table group by customername, address) t1
where t1.ct>1
This intrigued me since a friend had asked me something similar. The query below will solve the problem, albeit in-efficiently:
mysql> select DISTINCT CUSTOMER_NAME,CUSTOMER_ADDRESS from CUST_ADDR
where CUSTOMER_NAME in (select CUSTOMER_NAME from CUST_ADDR GROUP BY
CUSTOMER_NAME HAVING COUNT(DISTINCT CUSTOMER_ADDRESS) > 1 );
+---------------+----------------------+
| CUSTOMER_NAME | CUSTOMER_ADDRESS |
+---------------+----------------------+
| Bob Yonkers | 42 Satellite Cir |
| Bob Yonkers | 667 Orbit St |
| Ruby Tuesday | 123 Highway Ln Apt#1 |
| Ruby Tuesday | 123 Highway Ln |
+---------------+----------------------+
4 rows in set (0.01 sec)
Related
I have a table with data in the form
Date Amount Payer
04/01/2021 50 LARRY BURNS
16/01/2021 46 JOHN SMITH
15/01/2021 35 SUSAN ARTHUR
14/01/2021 28 S. ARTHUR
13/01/2021 21 JO SMITH
12/01/2021 13 LARRY BURNS
11/01/2021 6 SUSAN ARTHUR
I also have another table with data in the form
ID Customer Name Customer Type
10001 LARRY BURNS CU
10002 JOHN SMITH CU
10003 SUSAN ARTHUR CU
The first table which is a transactions table does not have a foreign key to reference the ID from the customer. The only information provided is the Payer column which includes inconsistently spelled names of customers. Is it possible to do some form of 'name matching' as a pseudo-join to allow retrieval of the customer name and ID?
Ideally in the form:
Date Amount Payer Customer Name ID
04/01/2021 50 LARRY BURNS LARRY BURNS 10001
16/01/2021 46 JOHN SMITH JOHN SMITH 10002
15/01/2021 35 SUSAN ARTHUR SUSAN ARTHUR 10003
14/01/2021 28 S. ARTHUR SUSAN ARTHUR 10003
13/01/2021 21 JO SMITH JOHN SMITH 10002
12/01/2021 13 LARRY BURNS LARRY BURNS 10001
11/01/2021 6 SUSAN ARTHUR SUSAN ARTHUR 10003
Given that you're willing to have an allowance for differences, you could try something like the following:
DECLARE #Payer table (
[Date] date, Amount decimal(18,2), Payer varchar(50)
);
INSERT INTO #Payer VALUES
( '01/04/2021', 50, 'LARRY BURNS' ),
( '01/16/2021', 46, 'JOHN SMITH' ),
( '01/15/2021', 35, 'SUSAN ARTHUR' ),
( '01/14/2021', 28, 'S. ARTHUR' ),
( '01/13/2021', 21, 'JO SMITH' ),
( '01/12/2021', 13, 'LARRY BURNS' ),
( '01/11/2021', 6 , 'SUSAN ARTHUR' );
DECLARE #Customer table (
ID int, CustomerName varchar(50), CustomerType varchar(2)
);
INSERT INTO #Customer VALUES
( 10001, 'LARRY BURNS', 'CU' ),
( 10002, 'JOHN SMITH', 'CU' ),
( 10003, 'SUSAN ARTHUR', 'CU' );
SELECT
[Date],
Amount,
Payer,
ID,
CustomerName
FROM #Payer AS payer
OUTER APPLY (
SELECT TOP 1
ID,
CustomerName
FROM #Customer AS c
WHERE
c.CustomerName = payer.Payer
OR
DIFFERENCE ( payer.Payer, c.CustomerName ) >= 3
OR
DIFFERENCE ( c.CustomerName, payer.Payer ) >= 3
) AS customer;
Returns
+------------+--------+--------------+-------+--------------+
| Date | Amount | Payer | ID | CustomerName |
+------------+--------+--------------+-------+--------------+
| 2021-01-04 | 50.00 | LARRY BURNS | 10001 | LARRY BURNS |
| 2021-01-16 | 46.00 | JOHN SMITH | 10002 | JOHN SMITH |
| 2021-01-15 | 35.00 | SUSAN ARTHUR | 10003 | SUSAN ARTHUR |
| 2021-01-14 | 28.00 | S. ARTHUR | 10003 | SUSAN ARTHUR |
| 2021-01-13 | 21.00 | JO SMITH | 10002 | JOHN SMITH |
| 2021-01-12 | 13.00 | LARRY BURNS | 10001 | LARRY BURNS |
| 2021-01-11 | 6.00 | SUSAN ARTHUR | 10003 | SUSAN ARTHUR |
+------------+--------+--------------+-------+--------------+
Table A
ID name date_from date_to region manager
---------------------------------------------------------
1 Harry 2019-12-01 2020-01-01 south ABC
1 Harry 2020-01-01 2020-03-01 north BCD
1 Harry 2020-03-01 NULL East DCE
Table B
Date name H_time T_time
---------------------------------------
2019-12-01 Harry 30 20
2020-01-01 Harry 20 10
2020-02-01 Harry 40 50
2020-04-01 Harry 50 60
I wanted to check table B date falls into the date range above and return the specific region and manager info like...
Table C
Date name H_time T_time region manager
---------------------------------------------------------
2019-12-01 Harry 30 20 south ABC
2020-01-01 Harry 20 10 north BCD
2020-02-01 Harry 40 50 north BCD
2020-04-01 Harry 50 60 East DCE
You can use a join:
select b.*, a.region, a.manager
from b join
a
on b.name = a.name and
b.date >= a.date_from and
(b.date <= date_to or a.date_to is null);
Based on your expected result, this should do the trick
SELECT b.*, a.region, a.manager
FROM table_b b
INNER JOIN table_a a on b.name = a.name
WHERE
(b.date >= a.date_from and b.date < a.date_to)
OR
(b.date >= a.date_from and a.date_to IS NULL)
This is my table:
EmployeeID Employee ManagerID
---------------------------------
1 Anna 5
2 John 4
3 Steve 4
4 Lisa 1
5 Adam NULL
6 Per 1
There is no problem for me to get parent and child relationship with a self-join like this:
SELECT
E.EmployeeID,
E.Employee AS Employee,
E.ManagerID,
M.Employee AS Manager
FROM
Employee AS E
LEFT JOIN
Employee AS M ON E.ManagerID = M.EmployeeID
EmployeeID Employee ManagerID Manager
1 Anna 5 Adam
2 John 4 Lisa
3 Steve 4 Lisa
4 Lisa 1 Anna
5 Adam NULL NULL
6 Per 1 Anna
However, How would i go about to make sure that the parent see the whole hierarchy level?
I would like the table to look like this:
EmployeeID Manager Employee EmployeeID
5 Adam Anna 1
5 Adam Per 6
5 Adam Lisa 4
5 Adam John 2
5 Adam Steve 3
1 Anna Per 6
1 Anna Lisa 4
1 Anna John 2
1 Anna Steve 3
4 Lisa John 2
4 Lisa Steve 3
Note: in this example i only have 3 levels of manger but there can be many more
You can try this:
DECLARE #DataSource TABLE
(
[EmployeeID] TINYINT
,[Employee] VARCHAR(12)
,[ManagerID] TINYINT
);
INSERT INTO #DataSource ([EmployeeID], [Employee], [ManagerID])
VALUES (1, 'Anna', 5)
,(2, 'John', 4)
,(3, 'Steve', 4)
,(4, 'Lisa', 1)
,(5, 'Adam', NULL)
,(6, 'Per', 1);
WITH DataSource AS
(
SELECT DISTINCT DS1.*
,0 AS [Level]
,DS1.[EmployeeID] AS Parent
FROM #DataSource DS1
INNER JOIN #DataSource DS2
ON DS1.[EmployeeID] = DS2.[ManagerID]
UNION ALL
SELECT DS2.*
,DS1.[Level] + 1
,DS1.Parent
FROM DataSource DS1
INNER JOIN #DataSource DS2
ON DS1.[EmployeeID] = DS2.[ManagerID]
)
SELECT DS1.[EmployeeID]
,DS1.[Employee] AS [Manager]
,DS.[EmployeeID]
,DS.[Employee]
FROM DataSource DS
INNER JOIN #DataSource DS1
ON DS.[Parent] = DS1.[EmployeeID]
WHERE DS.[Level] <> 0
ORDER BY DS.[Parent] DESC;
We are using recursive CTE and it may look a kind of messy and complicated if you are seeing this syntax for the first time, but it's nothing special.
When are using recursive CTE run some performance tests in order to be sure it is the right technique for solving your issue.
You should use recursive CTE syntax. In the first iteration (before UNION ALL) you get all Parent-Child pairs. In the recursive part (after UNION ALL) you get the next level child for each pair and substitute it into the pair Parent-Child instead of the Child leaving Parent the same.
WITH CTE AS
(
SELECT TP.EmployeeID as ManagerId,
TP.Employee as Manager,
TC.EmployeeID as EmployeeID,
TC.Employee as Employee
FROM TEmployee as TP
JOIN TEmployee as TC on (TP.EmployeeID = TC.ManagerID)
UNION ALL
SELECT TP.ManagerId as ManagerId,
TP.Manager as Manager,
TC.EmployeeID as EmployeeID,
TC.Employee as Employee
FROM CTE as TP
JOIN TEmployee as TC on (TP.EmployeeID = TC.ManagerID)
)
SELECT * FROM CTE Order By ManagerID
result:
+-----------+---------+------------+----------+
| ManagerId | Manager | EmployeeID | Employee |
+-----------+---------+------------+----------+
| 1 | Anna | 4 | Lisa |
| 1 | Anna | 6 | Per |
| 1 | Anna | 2 | John |
| 1 | Anna | 3 | Steve |
| 4 | Lisa | 2 | John |
| 4 | Lisa | 3 | Steve |
| 5 | Adam | 1 | Anna |
| 5 | Adam | 4 | Lisa |
| 5 | Adam | 6 | Per |
| 5 | Adam | 2 | John |
| 5 | Adam | 3 | Steve |
+-----------+---------+------------+----------+
I'm a Transact SQL newbie(SQL Server 2008).
I have a pivot table that is getting these results when I search for values by date range:
Person | 2/10/14 | 2/18/14
-----------+---------+---------
Jane Doe | NULL | QRS
June Jones | NULL | XYZ
Tom Smith | XYZ | HIK
But I need it to look like this, where June Jones has a value for 2/10/14:
Person | 2/10/14 | 2/17/14
-----------+---------+--------
Jane Doe | NULL | QRS
June Jones | XYZ | XYZ
Tom Smith | XYZ | HIK
The problem is that June Jones has an XYZ event which has a start_dt of 2/11/14 and end_date of 2/21/14 which should be in column '2/10/14' and my query seems to be missing it. The column of '2/17/14' is picking up the event.
My code:
WITH Numbers AS
(
SELECT '2/10/14' As n
UNION
SELECT '2/17/14' As n
) ,
Counted AS
(
SELECT s.[FirstName] + ' ' + s.[LastName] AS [Person],
CASE WHEN s.[Event] = 'Thing1' THEN 'HIK'
WHEN s.[Event] = 'Thing2' THEN 'QRS'
WHEN s.[Event] = 'Thing3' THEN 'XYZ'
ELSE NULL END AS [Info],
N.n AS DateWeek
FROM [dbo].[MyTable] s
INNER JOIN Numbers N ON DATEADD(DD,5,N.n) BETWEEN s.start_dt AND s.end_dt
WHERE s.LastName in ('Doe', 'Jones', 'Smith')
GROUP BY s.[FirstName] + ', ' + s.[LastName], s.[Info], N.n
)
SELECT [Person], '02/10/14', '2/17/14'
FROM Counted
PIVOT ( MAX(Info) FOR DateWeek IN ([2/10/14], [2/17/14] ))
AS PVT
I'm probably missing something obvious, but can't see it.
For 10th obiously it show null because your event start on 11th.
I am looking for the cleanest, shortest, simplest, and most efficient way to do this using T-SQL. I hope that a single way is all of those things, but I realize that it may not be.
I have tried (unsuccessfully) using PIVOT, but what I think I need is to PIVOT by chunks AND without aggregating
I queried a large table to obtain this result:
(the result is ordered by year by the Number descending. the Number is the Number of occurrences of people born with that Name in the given year)
Name Number Year
John 9655 1880
William 9532 1880
James 5927 1880
Charles 5348 1880
George 5126 1880
John 8769 1881
William 8524 1881
Charles 5442 1881
George 4664 1881
James 4636 1881
John 9557 1882
James 9298 1882
William 5892 1882
George 5193 1882
Charles 5092 1882
I want to turn the above result into this:
1880 1881 1882
John John John
William William James
James Charles William
Charles George George
George James Charles
You can use PIVOT to get the result, the only thing that you will need to do is add a row_number() that is generated by partitioning the data by year ordered by the number. This unique sequence then allows you to return multiple rows for each year when you apply the aggregate function. Also since you want to convert string data you need to use either the max or min aggregate function:
select [1880], [1881], [1882]
from
(
select name, year,
row_number() over(partition by year
order by number desc) seq
from yourtable
) d
pivot
(
max(name)
for year in ([1880], [1881], [1882])
) p;
See SQL Fiddle with Demo. Returns:
| 1880 | 1881 | 1882 |
|---------|---------|---------|
| John | John | John |
| William | William | James |
| James | Charles | William |
| Charles | George | George |
| George | James | Charles |