Display full records of duplicate entries across multiple columns - sql

I have a table (customers) that includes fields telephone_1, telephone_2, telephone_3 & telephone_4.
What I need to see is full records of where any telephone numbers are used in other customers - as I believe something has gone wrong with the data somewhere and customer numbers are duplicated into each other!
I have tried the below code, but this doesn't give me what I want as only compares 1/1, 2/2, 3/3 & 4/4. I have an ID field which can be used to differentiate between records.
SELECT *
FROM Customers AS a
WHERE 1 < (SELECT Count(*)
FROM Customers AS b
WHERE a.Telephone_1 = b.Telephone_1
OR a.Telephone_2 = b.Telephone_2
OR a.Telephone_3 = b.Telephone_3
OR a.Telephone_4 = b.Telephone_4
Any assistance is appreciated - thanks!

How about this?
SELECT *
FROM Customers AS a
WHERE 1 < (
SELECT Count(*)
FROM Customers AS b
WHERE a.Telephone_1 IN (b.Telephone_1, b.Telephone_2, b.Telephone_3, b.Telephone_4)
OR a.Telephone_2 IN (b.Telephone_1, b.Telephone_2, b.Telephone_3, b.Telephone_4)
OR a.Telephone_3 IN (b.Telephone_1, b.Telephone_2, b.Telephone_3, b.Telephone_4)
OR a.Telephone_4 IN (b.Telephone_1, b.Telephone_2, b.Telephone_3, b.Telephone_4)
)
========Take 2=======
Following the comments:
Create a new table with telephone numbers nd customer IDs
CREATE TABLE tempTelephoneNos (
INTEGER customer,
VARCHAR(32) telephoneNo
);
assuming those are the appropriate data types for the customer Id and phone no.
Populate the new table
INSERT INTO tempTelephoneNos (customer, telephoneNo)
SELECT customer_id, telephone_1
FROM customers
UNION ALL
SELECT customer_id, telephone_2
FROM customers
UNION ALL
SELECT customer_id, telephone_3
FROM customers
UNION ALL
SELECT customer_id, telephone_4
FROM customers
Then you can find out which telephone numbers appear for more than one customer with
SELECT customer, telephoneNo
FROM tempTelephoneNos
WHERE 1 < (SELECT COUNT(*) FROM tempTelephoneNos GROUP BY telephoneNo)

Related

Fetching duplicate records based on a column value in ORACLE

So I have a customer database which has Customer_Account_ID, Phone_No and Alt_Phone_No. Now the Alt_Phone_No can have a number value or it can have blank. I want a output where the data is in below format:
Let’s say customer id is 12345678
Phone numbers are 4021234444 and 4022221234
We should have two rows on the spreadsheet:
Customer ID Phone number
12345678 4021234444
12345678 4022221234
If there is no value in Alt_Phone_No, then there shouldn't be any second entry i.e. need just the Customer ID and Phone Number in such case.
What I have roughly came up is with below:
SELECT Customer_Account_ID, Phone_No FROM Table_A a,
(SELECT Customer_Account_ID, Phone_No FROM Table_A, Table_B
where Table_A.Cust_ID = Table_B.Cust_ID
and condition = ' ' /*filter needed as per requirements*/
UNION ALL
SELECT Customer_Account_ID, Alt_Phone_No FROM Table_A, Table_B
where Table_A.Cust_ID = Table_B.Cust_ID
and condition = ' ' /*filter needed as per requirements*/ ) b
where a.Cust_ID = b.Cust_ID
and rownum < 1000 /*need rownum for testing sample data as the original data is too large*/
order by a.Cust_Id
I believe the query is incorrect. Would appreciate all the suggestions and inputs.
You can use union all:
select customerid, phonenumber
from t
union all
select customerid, altphonenumber
from t
where altphonenumber is not null;

how to list booking ref code and names of passengers in bookings with 3 or more passengers together with sql

here is the dataset 'ticket'
I need to retrieve a list of book_ref and names passengers in bookings with 3 or more passengers together .
I tried store the result in existed table booking_code
INSERT INTO booking_code
SELECT book_ref, passenger_name
FROM bookings.ticket
GROUP BY book_ref, passenger_name
/*looking for br have 2 airport
*/
HAVING COUNT( * ) >2;
but the result was 2 empty column of book_ref and passenger_name
I think I did not correctly use "count".
how can i fix to code so the outcome would be like this?
You seem to want window functions:
SELECT t.book_ref, t.passenger_name
FROM (SELECT t.*, COUNT(*) OVER (PARTITION BY book_ref) as book_ref_cnt
FROM bookings.ticket t
) t
WHERE book_ref_cnt > 2;
This returns booking with more than 2 passengers in the original data.

SQL Divide one count result by another OR Alternate solution

I have a table with the following schema.
Relational Database Schema:
Hotel = hotelNo, hotelName, city
Room = roomNo, hotelNo(FK), type, rate
Guest = guestNo, guestName, guestAddress
Booking = hotelNo(FK), guestNo(FK), dateFrom, dateTo, roomNo(FK)
There are entries in each table however their data isn't completely relevant to this question.
I need to calculate the average number of booking made for each hotel, ensuring that I include the hotels which do not currently have bookings.
I have this :
-- Call this select 1
select count(*)
from booking b, hotel h
where b.hotelNo=h.hotelNo;
-- Call this select 2
select count(*)
from hotel;
Select 1 returns the total number of bookings. Select 2 returns the total number of hotels. If I could simply divide the output of count in select 1 by the output of count in select 2 I would have my answer.
If this is possible can someone please help me with the code, otherwise can someone think of an alternate solution to achieve the same result?
If by "average number of bookings", you just want to divide the two numbers, then you can do:
select count(b.HotelNo) / count(distinct h.hotelNo)
from hotel h left join
booking b
on h.hotelNo = b.hotelNo;
Create a view say temp to get count of rooms per hotel[ The data you 'see' in a view, is not actually stored anywhere, and is generated from the tables on the fly.]
create view temp
as select hotelNo,count(*) as cnt from room group by hotelNo;
Use following query to fetch avg.
select booking.hotelNo,count(*) / cnt
from booking ,temp
where booking.hotelNo = temp.hotelNo
group by booking.hotelNo;
or
select booking.hotelNo,count(*) / cnt
from booking
INNER JOIN temp
on booking.hotelNo = temp.hotelNo
group by booking.hotelNo;
This will not include hotels that do not have any booking.

sql program with Group by 2 attributes and 1 condition (Import)

I have a text file that contains Candy issued data.
File contains customer id, issue date, candy name.
C1,2014-01-01,Candy1
C1,2014-01-02,Candy2
C2,2002-06-01,Candy2
C1,2014-01-02,Candy3
C2,2002-06-01,Candy3
I am trying to figure out how can I write a program that creates a list of pairs of candies which were issued together i.e. issued to the same customer on the same day at least twenty-five different times.
Thanks in advance.
--create a table to hold our data
create table CandySales
(
CustomerId nchar(2)
, SaleDate Date
, CandyId nvarchar(10)
)
--upload the data from the csv
bulk insert CandySales
from 'c:\temp\myCsv.csv'
with (fieldterminator = ',', rowterminator = '\n')
--query the data
;with cte as
(
select customerId, candyId, saleDate
from CandySales
group by customerId, candyId, saleDate
having COUNT(1) >= 25
)
select distinct
a.CandyId Item1
, b.CandyId Item2
from cte a
inner join cte b
on a.CandyId > b.CandyId
and a.SaleDate = b.SaleDate
and a.CustomerId = b.CustomerId
Explanation of Query
The cte creates a list of all candies which have had 25 or more sales to the same customer on the same day.
include distinct as we may have the same pair returned for multiple dates/customers; we only want each pair once.
on a.CandyId > b.CandyId is used as we want to ensure the pair contains different candies from one another. We use > instead of != to avoid getting the same pair with item1 and item2 reversed.
we then join on sale date and customer date as we want items which were sold to the same customer on the same day.

How to get records from both tables using ms access query

I have 2 Tables in Ms Access
tbl_Master_Employess
tbl_Emp_Salary
I want to show all the employees in the employee table linked with employee salary table
to link both table the id is coluqEmpID in both table
In the second table, I have a date column. I need a query which should fetch records from both tables using a particular date
I tried the following query:
select coluqEID as EmployeeID , colEName as EmployeeName,"" as Type, "" as Amt
from tbl_Master_Employee
union Select b.coluqEID as EmployeeID, b.colEName as EmployeeName, colType as Type, colAmount as Amt
from tbl_Emp_Salary a, tbl_Master_Employee b
where a.coluqEID = b.coluqEID and a.colDate = #12/09/2013#
However, it shows duplicates.
Query4
EmployeeID EmployeeName Type Amt
1 LAKSHMANAN
1 LAKSHMANAN Advance 100
2 PONRAJ
2 PONRAJ Advance 200
3 VIJAYAN
4 THIRUPATHI
5 VIJAYAKUMAR
6 GOVINDAN
7 TAMILMANI
8 SELVAM
9 ANAMALAI
10 KUMARAN
How would I rewrite my query to avoid duplicates, or what would be a different way to not show duplicates?
The problem with your query is that you are using union when what you want is a join. The union is first going to list all employees with the first part:
select coluqEID as EmployeeID , colEName as EmployeeName,"" as Type, "" as Amt
from tbl_Master_Employee
and then adds to that list all employee records where they have a salary with a certain date.
Select b.coluqEID as EmployeeID, b.colEName as EmployeeName, colType as Type,
colAmount as Amt
from tbl_Emp_Salary a, tbl_Master_Employee b
where a.coluqEID = b.coluqEID and a.colDate = #12/09/2013#
Is your goal to get a list of all employees and only display salary information for those who have a certain date? Some sample data would be useful. Assuming the data here: SQL Fiddle this query should create what you want.
Select a.coluqEID as EmployeeID, colEName as EmployeeName,
b.colType as Type, b.colAmount as Amt
FROM tbl_Master_Employees as a
LEFT JOIN (select coluqEID, colType, colAmount FROM tbl_EMP_Salary
where colDate = '20130912') as b ON a.coluqEID = b.coluqEID;
The first step is to create a select that will get you just the salaries that you want by date. You can then perform a join on this as if you were performing a separate query. You use a LEFT JOIN because you want all of the records from one side, the employees, and only the records that match your criteria from the second side, your salaries.
I believe you will need a join, however as to your question on Unique names.
select **DISTINCT** coluqEID as EmployeeID
Adding the distinct operator would give only uniquely returned results.