Returning DISTINCT rows in sql query - sql

I have two tables. One is clients, that has a clientID and entity, the other is LogOnLink which has a clientID and LogonID. The LogOnLink table can the same clientID entered into it multiple times. So i'm trying to run a query where I do a search for an Entity Joining the LogonLink table. The problem i'm having is that if an entity is in the logonLink table 20 times, i get the name returned twenty times. How do i make it so that it only shows me one instance of an entity. Keep in mind that there can be similar entity names so If i have "Company 1" and "Company 2" in the db, i need to show both companies if someone types in companies. I tried doing DISTINCT but it doesn't distinct it by clientID in the LogOnLink table. Here's what i have so far.
SELECT DISTINCT ll.logonID, entity
FROM clients c
INNER JOIN LogOnsLink ll ON ll.clientID = c.clientID
WHERE c.entity LIKE '%Com%'
ORDER BY entity
Clients Table
------------------------------------
clientID entity
2 Company A
8 Company B
43 Company C
LogOnLinks Table
------------------------------------
LogonLinkID clientID LogonID
4 2 3
5 2 7
21 8 20
6 2 9
3 8 10
45 43 3

You'll need to perform some kind of aggregate on the data from LogOnsLink or you'll always get 20 rows...
Try this
SELECT entity, COUNT(ll.logonID) AS MaxlogonIDs
FROM clients c
INNER JOIN LogOnsLink ll ON ll.clientID=c.clientID
WHERE c.entity LIKE '%Com%'
GROUP BY entity
ORDER BY entity
or
SELECT DISTINCT entity
FROM clients c
INNER JOIN LogOnsLink ll ON ll.clientID=c.clientID
WHERE c.entity LIKE '%Com%'
ORDER BY entity

Try this
SELECT ll.logonID, DISTINCT(entity)
FROM Clients c INNER JOIN LogOnsLink ll
ON ll.clientID=c.clientID
WHERE c.entity LIKE '%Com%'
ORDER BY entity

Related

SQL Join to return data from The Same Column in the same table to two diffrent rows in result (Star Wars Example)

Newbie question about joining tables. I want to retrieve a name from a column TWICE in a SQL statement, and I'm running in circles.
I Have two Tables - "Company" & "People"
Table -"People"
ID
Name
Phone
1
Luke
555-1212
2
Leia
555-1234
3
Han
999-8888
4
Anikin
888-9876
5
Obi-wan
555-1212
6
R2-D2
#% - **!?
Table - "Company"
ID
CompanyName
PrimaryContact
AltContact
1
Speeders R Us
5
1
2
Droid Repair World
6
4
3
Luke's Second Hand Store
1
4
4
Cloak World
4
5
5
Ye Old Blaster Shoppe
3
2
If I want to get a result that gives BOTH the Contact Names for a Company, How would I do it?
I can get the PrimaryContact to JOIN Properly using something like...
SELECT C.*, P.Name as 'Primary'
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
WHERE C.ID =3
which successfully returns
ID
CompanyName
PrimaryContact
AltContact
Primary
3
Luke's Second Hand Store
1
4
Luke
But for the life of me, I can't figure out how to modify this SQL to also return "Anikin" as the Alternate Contact. Is this an example of where a UNION statement would help?
You can join to the same table multiple times, just give a new alias every time.
Join People P on C.PrimaryContact = P.ID
Join People P1 on C.AltContact = P1.ID
Join People altcontact on C.AltContact = altcontact.ID
Join People P256 on C.yetanotheralternateContact = P256.ID
You need to to join for ecervy contact another Persons table
SELECT C.ID,C.CompanyName, P.Name as 'Primary' , P.Phone As 'primary_Phone', P2.Name on 'Alternative', P2.Phone as 'Alternatibe_Phone
FROM `Company` C
Join People P on
C.PrimaryContact = P.ID
Join People P2 on
C.AltContact = P2.ID
WHERE C.ID

SQL Selecting & Counting In the same query

thanks in advance for any help on this, I am a bit of a newbie to MS SQL and I want to do something that I think is achievable but don't have the know how.
I have a simple table called "suppliers" where I can do (SELECT id, name FROM suppliers ORDER BY id ASC)
id
name
1
ACME
2
First Stop Business Supplies
3
All in One Supply Warehouse
4
Farm First Supplies
I have another table called "products"
id
name
supplier_id
1
Item 1
2
2
Item 2
1
3
Item 3
1
4
Item 4
3
5
Item 5
2
I want to list all the suppliers and get the total amount of products for each supplier if that makes sense on the same row? I am just not sure how to pass the suppliers.id through the query to get the count.
I am hoping to get to this:
id
name
total_products
1
ACME
2
2
First Stop Business Supplies
2
3
All in One Supply Warehouse
1
4
Farm First Supplies
0
I really appreciate any help on this.
Three concepts to grasp here. Left Join, group by, and Count().
select s.id, s.name, Count(*) as total_products
from suppliers s
left join products p on s.id=p.supplier_id --the left join gets your no matches
group by s.id, s.name
left join is a join where all of the values from the first table are kept even if there are no matches in the second.
Group by is an aggregation tool where the columns to be aggregated are entered.
Count() is simply a count of transactions for the grouped columns.
Try this :-
SELECT id, name, C.total_products
FROM Suppliers S
OUTER APPLY (
SELECT Count(id) AS total_products
FROM Products P
WHERE P.supplier_id = S.id
) C

How to find all the pairs of tuples that agree on a certain attribute

I am trying to write a query in db2 for a database that has books and the customers who bought them and I am to find the pairs of customers who bought common books.
Say for example the DB is called "DB" and it looks like this
CustomerID Book Cost
1 Harry Potter 12
2 SOUE 6
3 Harry Potter 12
4 Harry Potter 12
5 SOUE 6
6 SOUE 6
I am basically trying to get the resulting table look like
Customer1 Customer2
1 3
1 4
2 5
2 6
I have tried using group by's but I cant seem to get the idea right
I've tried
Select book
from DB
group by book
which uniquely gives me all the books but I don't know how I would go about getting the customer pairs. Any help would be greatly appreciated thank you.
I'd self-join according to the book column. In order to avoid conceptual duplicates (e.g., 1-3 and 3-1), you could make an arbitrary decision to always display the lower customer ID on the left:
SELECT DISTINCT a.customerid, b.customerid
FROM mytable a
JOIN mytable b ON a.book = b.book AND a.customerid < b.customerid
EDIT:
To answer the question in the comments, if you want to display customer names instead of ids, you'd need to join the customers table to this query, twice, once for each column:
SELECT DISTINCT ca.name AS customer1, cb.name AS customer2
FROM purchases pa
JOIN purchases pb ON pa.book = pb.book AND pa.customerid < pb.customerid
JOIN customers ca ON pa.customer_id = ca.id
JOIN customers cb ON pb.customer_id = cb.id

SQL Lookup data in joined table based on LIKE value stored in joined table column

I am trying to build a query that will look up a product_subcategory based on a reference data in a user entered table and joining two tables together. My database is SQL Server 2012 Express.
First the products table has three columns: Product_id (unique identifier), event_id (INT data type), and product_category. (product_category needs to be alphanumeric currently varchar(32) data type)
Example Products table data:
Product_id event_id product_category
1 20 100
2 20 105
3 20 200
4 21 100
5 21 200
6 21 203
7 22 105
8 22 207
Second the events table has two columns: event_id (unique identifier, INT Data type) and zone (float data type, not sure why this was setup as float, probably should have been INT but its a pre-existing table and I don't want to change it)
event_id zone
20 1
21 2
22 3
Third the subcategory table has four columns: subcategory_id (unique identifier, INT data type), zone (joins to zone column in products table, INT Data type), category_lookup (varchar(max) data type), and product_subcategory (varchar(50) data type). This is a table that I am creating for this project so I can change the structure or datatypes to be whatever is needed for the project, I don't have that flexibility on the other tables.
Example Subcategory table data:
subcategory_id zone category_lookup product_subcategory
1 1 '1%' 25
2 1 '2%' 23
3 2 '1%' 26
4 2 '2%' 30
I want to build a query that will search the product table and match a zone, product_category, and product_subcategory together based on the value in the subcategory.category_lookup column.
The data that I want returned from the query is:
product_ID zone product_category product_subcategory
1 1 100 25
2 1 105 25
3 1 200 23
4 2 100 26
5 2 200 30
6 2 203 30
7 3 105 NULL or 'N/A'
8 3 107 NULL or 'N/A'
The logic behind looking up the matching subcategory will be similar to below: (this is essentially what is stored in the subcategory table) (the text in the “quotes” is what I mean by reference data, and will be user entered)
IE... if zone = 1 and product_category “begins with 1” then product_subcategory = 25
IE... if zone = 1 and product_category “begins with 2” then product_subcategory = 23
IE... if zone = 2 and product_category “begins with 1” then product_subcategory = 26
IE... if zone = 2 and product_category “begins with 2” then product_subcategory = 30
I do understand that one of the issues with my logic is that if multiple subcategories match to one product then it will throw an error, but I think I can code around that once I get this part of it working
I am fine going a different direction with this project but this is the first way I decided to tackle it. The most important component is that the product_subcategory’s are going to be located in a separate user entered table, and there needs to be user entered logic as discussed above to determine the product_subcategory based on zone and product_category.
I am not a SQL guru at all so I don’t even know where to start to handle this problem. Any advice is appreciated.
Based on answers I have received so far I have come up with this:
SELECT p.product_id, p.event_id, e.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN events e on p.event_id = e.event_id
LEFT JOIN SubCategory sc ON e.zone = sc.zone AND CAST(p.product_category as varchar(max)) like sc.category_lookup
But unfortunately its only returning NULL for all of the product_subcategory results.
Any additional help is appreciated.
Thanks,
This should do the trick, you will just need to modify the CAST(p.zone as nchar(10)) to insert the correct data type for your category_lookup column, in place of nchar(10), as I assume the zone in Products is an int where as the lookup column is some string based column:
SELECT p.product_id, p.zone, p.product_category, sc.product_subcategory
FROM Products p
LEFT JOIN SubCategory sc ON p.zone = sc.zone
AND CAST(p.zone as nchar(10)) like sc.category_lookup
Based on your updates, the following should work:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(e.zone as nchar(250)) LIKE CAST(sc.category_lookup as nchar(250))
Update based on comments:
SELECT p.product_id, p.event_id, e.zone, p.product_category,
sc.product_subcategory
FROM Products p
INNER JOIN events e on p.event_id = e.event_id
LEFT OUTER JOIN SubCategory sc ON e.zone = sc.zone
AND CAST(p.product_category as nchar(250)) LIKE sc.category_lookup
Working sample SQLFiddle
Not tested but is this what you're looking for ?
select a.product_ID, a.zone, a.product_category, b.product_subcategory
from Products a
inner join Subcategory on ((a.zone = b.zone) and (a.product_category like b.category_lookup))
Try this..
select p.product_id, p.zone, p.product_category, isnull(s.product_subcategory,'NA') as product_subcategory
from Products p
left outer join Subcategory s on (s.zone = p.zone and p.product_category like s.category_lookup);

NHibernate + join to derived table

In a table that stores multiple rows per employee, I want to pull one row per employee that represents the most recent entry for each employee. Here's where I am with hand-written SQL:
SELECT [all the selected columns here]
FROM Nominations t
inner join
(select max(NominationId) mostRecentNominationId,
EmployeeId from Nominations group by EmployeeId) n
on n.mostRecentNominationId = t_.NominationId
From source data like this:
nomination_id employee_id
-------------------------------
1 5
2 5
4 10
7 10
That'll give me something like this:
nomination_id employee_id
-------------------------------
2 5
7 10
I haven't been able to figure out how to accomplish that type of query via NHibernate ICriteria. Any thoughts?
Here is what you need to do:
DetachedCriteria dCriteria = DetachedCriteria.For<Nomination>("nomination")
.SetProjection(Projections.Max("nomination.Id"))
.Add(Restrictions.EqProperty("nomination.EmployeeId", "employee.Id"));
var nominations = Session.CreateCriteria<Nomination>("nom")
.CreateCriteria("Employee", "employee")
.Add(Subqueries.PropertyEq("nom.Id", dCriteria)).List<Nomination>();
This is not equilevant to the SQL query providfed in the question but it does exactly the same thing.
The SQL query that is generated by the above criteria query is:
SELECT *
FROM Nomination nom
inner join Employee employee on nom.EmployeeId=employee.EmployeeId
WHERE nom.NominationId =
(SELECT max(nomination.NominationId) as maxID
FROM Nomination nomination
WHERE nomination.EmployeeId = employee.EmployeeId)