Select name from SQL column - sql

I am trying to select the names (along with the rest of the information on the table such as data, time, lesson) of each user that is inside a users table. The names I'm trying to select are the ones that are on the same row as a particular teacherID. However when I run this code I'm getting the same name for all records, when I should be getting two different ones.
SELECT FName, SName, bookedLessons.bookedHour,
bookedLessons.bookedDate, bookedLessons.lesson
FROM users JOIN bookedLessons
WHERE teacherID = 11
AND users.userID = (SELECT userID FROM bookedLessons WHERE teacherID = 11)

Your join needs an ON clause but not the subquery in the WHERE clause:
SELECT u.FName, u.SName, b.bookedHour, b.bookedDate, b.lesson
FROM bookedLessons b INNER JOIN users u
ON u.userID = b.userID
WHERE b.teacherID = 11

Related

Show rows with at least one occurrence in a relation table?

I have the following table schema:
user (id, name, alias, password, active, mail, age)
comment(id, news(FK), user(FK), text, date)
new_cat(news(FK), category(FK))
I'm trying to select all the users who have commented on AT LEAST one new of EVERY category.
This is what I'm trying without any success:
SELECT * FROM user AS u, comment AS c
WHERE u.id = c.user AND c.news IN (SELECT news FROM new_cat);
I believe this is not iterating properly and checking for EVERY category and just checks if the condition applies just on one category.
How can I properly do this?
Join the tables, group by user and set the condition in the HAVING clause.
If there is a category table where you store all the categories:
SELECT u.*
FROM user u
INNER JOIN comment c ON c.user = u.id
INNER JOIN new_cat n ON n.news = c.news
GROUP BY u.id
HAVING COUNT(DISTINCT n.category) = (SELECT COUNT(*) FROM category);

Remove duplicates from result in sql

i have following sql in java project:
select distinct * from drivers inner join licenses on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false
And result i database looks like this:
And i would like to get only one result instead of two duplicated results.
How can i do that?
Solution 1 - That's Because one of data has duplicate value write distinct keyword with only column you want like this
Select distinct id, distinct creation_date, distinct modification_date from
YourTable
Solution 2 - apply distinct only on ID and once you get id you can get all data using in query
select * from yourtable where id in (select distinct id from drivers inner join
licenses
on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false )
Enum fields name on select, using COALESCE for fields which value is null.
usually you dont query distinct with * (all columns), because it means if one column has the same value but the rest isn't, it will be treated as a different rows. so you have to distinct only the column you want to, then get the data
I suspect that you want left joins like this:
select *
from users u left join
drivers d
on d.user_id = u.id and d.status = 'WAITING' left join
licenses l
on d.user_id = l.issuer_id and l.state = 'ISSUED'
where u.is_deleted = false and
(d.user_id is not null or l.issuer_id is not null);

Select Count Distinct the value to get unique data

i'm very new in sql and dont have an idea for this even simple one.
table 1 bos_report_users contain user_id,dept,branch_code table 2 bos_report_access contain user_id,report_id
i would like join this table so the result should be something like this
dept | user_id|report_id|.
this is what i have done and result is not what i'm expected.
SELECT A.USER_ID,B.REPORT_ID
FROM(SELECT DISTINCT DEPT FROM BOS_M_USERS WHERE DEPT='FINANCE'),BOS_REPORT_ACCESS B ,BOS_M_USERS A
WHERE A.USER_ID='SLTAM'
kindly assist me everyone. thanks for helping.
The join is performed through the shared column user_id
SELECT
u.user_id, u.dept, u.branch_code
, a.report_id
FROM bos_report_users u
INNER JOIN bos_report_access a ON u.user_id = a.user_id
WHERE u.user_id = 'SLTAM'
ORDER BY u.dept, u.user_id
alias "u" = users
alias "a" = access

SQL - Removing Duplicate Rows but Keeping Null Rows

Happy New Year SO!
Problem
I'm writing a stored procedure that takes in a list of User Ids and it should return 1 record per user id that contains:
User details from the User table (first name, last name etc)
Latest modified address record from the Address table. If there IS NO Address record, then we need to return NULL in the address fields (Address, Postcode etc)
Country details from the Country table (Region etc)
Now I have the following, which is correctly returning NULL's for no address details (last record in the screen shot) BUT for a User Id that has multiple address records, I'm having multiple records returned and NOT the lastest modified address record:
SELECT
U.Id, U.FirstName, U.Surname, U.Email, U.DateOfBirth,
AD.AddressLine1, AD.AddressLine2, AD.AddressLine3,
AD.PostCode, AD.Nickname, AD.Phone, AD.Modified,
CNT.Name, CNT.Code,
a.MaxDate
FROM
#TableVariable AS List
LEFT JOIN
dbo.Users AS U ON List.Id = U.Id
LEFT JOIN
dbo.Addresses AS AD ON U.Id = AD.User_Id
LEFT JOIN
(SELECT
JA.User_Id, MAX(CONVERT(DATE,JA.Modified,10)) AS MaxDate
FROM dbo.Addresses AS JA
GROUP BY JA.User_Id) A ON (AD.User_Id = A.User_Id AND CONVERT(DATE,AD.Modified,10) = A.MaxDate)
LEFT JOIN
dbo.Countries AS CNT ON AD.Country_Id = CNT.Id
ORDER BY
AD.Modified DESC
Here is the result set after running the above. As you can see I have correctly got my record returned for a User WITHOUT an address (Last record) but I'm getting 3 records for 2108 when I wanted 1, inlcuding the latest modified address (AD.Modified).
I'm using SQL Server 2008.
You can use outer apply and order by to get the latest record, with something like this:
FROM #TableVariable AS List
LEFT JOIN dbo.Users AS U
ON List.Id = U.Id
OUTER APPLY (
SELECT top 1 *
FROM dbo.Addresses AS JA
WHERE U.Id = JA.User_Id
order by Modified DESC
) AD
LEFT JOIN dbo.Countries AS CNT
ON AD.Country_Id = CNT.Id
ORDER BY AD.Modified DESC

Where clause on joined table used for user defined key/value pairs

Our application allows administrators to add “User Properties” in order for them to be able to tailor the system to match their own HR systems. For example, if your company has departments, you can define “Departments” in the Properties table and then add values that correspond to “Departments” such as “Jewelry”, “Electronics” etc… You are then able to assign a department to users.
Here is the schema:
(source: mindgravy.net)
In this schema, a User can have only one UserPropertyValue per Property, but doesn’t have to have a value for the property.
I am trying to build a query that will be used in SSRS 2005 and also have it use the PropertyValues as the filter for users. My query looks like this:
SELECT UserLogin, FirstName, LastName
FROM Users U
LEFT OUTER JOIN UserPropertyValues UPV
ON U.ID = UPV.UserID
WHERE UPV.PropertyValueID IN (1, 5)
When I run this, if the user has ANY of the property values, they are returned. What I would like to have is where this query will return users that have values BY PROPERTY.
So if PropertyValueID = 1 is of Department (Jewelry), and PropertyValueID = 5 is of EmploymentType (Full Time), I want to return all users that are in Department Jewelry that are EmployeeType of Full Time, can this be done?
Here's a full data example:
User A has Department(Jewelry value = 1) and EmploymentType(FullTime value = 5)User B has Department(Electronics value = 2) and EmploymentType(FullTime value = 5)User C has Department(Jewelry value = 1) and EmployementType(PartTime value = 6)
My query should only return User A using the above query
UPDATE:
I should state that this query is used as a dataset in SSRS, so the parameter passed to the query will be #PropertyIDs and it is defined as a multi-value parameter in SSRS.
WHERE UPV.PropertyValueID IN (#PropertyIDs)
I figured out how to get this working in a completely hacky fashion:
SELECT UserLogin, FirstName, LastName
FROM Users
LEFT OUTER JOIN
(
SELECT UserID
FROM UserPropertyValues
WHERE PropertyValueID IN (#PropertyIDs)
GROUP BY UserID
HAVING COUNT(UserID) =
(
SELECT COUNT(*) FROM
(
SELECT PropertyID FROM PropertyValues
WHERE ID IN (#PropertyIDs) GROUP BY PropertyID
) p
)
) filtered on Users.UserID = filtered.UserID
Because we can determine the number of properties used in the parameter #PropertyIDs (returned by the select count(*)), we can make sure that the users returned from the query has the same number of properties as what was passed in #PropertyIDs.
SELECT UserLogin, FirstName, LastName
FROM Users
where UserID in (
select UserID
from UserPropertyValues upv1
inner join UserPropertyValues upv2 on upv1.UserID = upv2.UserID
and upv1.PropertyValueID = 1 and upv2.PropertyValueID = 5
) a
You need to join to the key_value store individually for each property you want to get (2 properties, 2 joins, 100 properties, 100 joins), This is why it is a poor design choice for performance.
Expanding on OrbMan's answer. This is going to give you one row per user/property.
SELECT U.UserLogin, U.FirstName, U.LastName, P.Name AS PropertyName, PV.Name AS PropertyValue
FROM Users U
INNER JOIN UserPropertyValues UPV
ON U.ID = UPV.UserID
INNER JOIN Properties P
ON UPV.PropertyID = P.ID
INNER JOIN PropertyValues PV
ON UPV.PropertyID = PV.ID
where UserID in (
select UserID
from UserPropertyValues upv1
inner join UserPropertyValues upv2 on upv1.UserID = upv2.UserID
and upv1.PropertyValueID IN (#PropertyIDs))