I have 2 questions, one about SQL and one about Entity Framework:
I have a table "UserSet" with all information about the user; and I have the table "FriendRequests", that handles UserID and FriendID information. My current user is "rugardini". I need to list the Friends requests. So, I did a query like this only for testing purposes:
select fq.FriendID, u.Nickname from
FriendRequestsSet as fq, UserSet as u
where fq.UserID=16
But my result is like this:
| FriendID | Nickname |
------------------------
| 17 |rugardini |
| 17 | Teste |
== edited ====================
Now I realize my query should be:
SELECT u.ID, u.Nickname
FROM UserSet as u, FriendRequestsSet as f
WHERE u.ID=f.FriendID
ORDER BY u.ID
I'm getting the right result ^^ I still need to know how to "translate" it to EF4.1?
Rubia in Linq its almost similar
from u in USerSet
join f in FriendRequestsSet
on u.ID=f.FriendID
ORDERBY u.ID
select new {u.ID,u.Nickname}
for using this query you would like to use different column from each table to create a new view (as we do in sqlserver). We need to create a Viewmodel in MVC that will represent columns
public class FriendRequest
{
int col1{get;set;}
int col2{get;set;}
//Here comes the Column You Want To Consider For your View Model
}
var list=from u in USerSet
join f in FriendRequestsSet
on u.ID=f.FriendID
ORDERBY u.ID
select new FriendResquest{Col1=u.ID,col2=u.Nickname}
//Here by map your columns as declared in your view model
Related
I am new in Sql. My question is how to get data from three different tables with null values.
I have tried a query as below:
SELECT *
FROM [USER]
JOIN [Location] ON ([Location].UserId = [USER].Id)
JOIN [ParentChild] ON ([ParentChild].UserId = [USER].Id) WHERE ParentId=7
which I find from this link.
Its working fine but, it not fetches all and each data associated with the ParentId
Something like it only fetches data which are available in all tables, but also omits some data which not available in Location tables but it comes under the given ParentId.
For example:
+----------+-------------+
| UserId | ParentId |
+----------+-------------+
| 1 | 7 |
+----------+-------------+
| 8 | 7 |
+----------+-------------+
For userId 8, there is data available in Location table,so it fetches all data. But there is no data for userId 1 available in Location table, so the query didn't work for this.
But I want all and every data.
If there is no data for userId then it can return only null columns.
Is it possible ??
hope everyone can understand my problem.
If you always want to return a list of users, but some may not have locations then you want to change the type of join from an "Inner Join" (or as you have used the short hand "JOIN") to a "Left Join".
SELECT *
FROM [USER]
INNER JOIN [ParentChild] ON ([ParentChild].UserId = [USER].Id)
LEFT JOIN [Location] ON ([Location].UserId = [USER].Id)
WHERE ParentId=7
This doesn't account for users that do not have a parent. If you still want to return users who do not have a parent then you would then need to change the JOIN type to your ParentChild table to a LEFT join also.
Edit: this isn't to be a dynamic output, the output view structure is fixed.
I am trying to create a SQL Server view that shows a single fixed column row for each user, and flattens out an associated one to many table into that row.
Although the associated table has a one to many relationship, the output table structure is limited to 4 elememts form that table.
My table structure is like so:
User (Id, FirstName, LastName)
Assessment (Id, Date, Location, User_Id)
Topics (Id, Topic, Assessment_Id)
Where the Assessment is joined to the User by the User_Id (One 2 One), and the Topics are joined to the Assessment by the Assessment_Id.
So, if I have three topics for an assessment, I'd want the view to look something like:
User_Id | FirstName | LastName | Date | Location | Topic1 | Topic2 | Topic3 | Topic4 |
1 | dave | toby | 2/2/11 | In situ | apples | pears | lemons | NULL |
My current SQL looks like this:
SELECT User.Id, User.FirstName, User.LastName, Assessment.Date, Assessment.Location, Topic.Topic
FROM User LEFT OUTER JOIN
Assessment INNER JOIN
Topic ON Assessment.Id = Topic.Assessment_Id ON
User.Id = Assessment.User_Id
But this returns a row for each concern - it doesn't compress them to one line. I've played with a few different joins, but haven't been able to get the behaviour I want.
Is it possible to do this in a view?
What do I need to do to make it happen??
Thanks!
There is no such JOIN. SQL has a fixed column output: so you can't add arbritrary numbers of columns. It doesn't matter if it's a view, direct or in a stored procedure.
There are 2 main options
concatenate the many rows into one column which is a popular questions here on SO. One random solution using XML PATH
use dynamic SQL to add a column per row in a stored procedure.
Note: PIVOT is fixed column output too
Edit: for a maximum of 4 child rows
SELECT
P.col1, P.col2,
C1.col1 AS Topic1,
C2.col1 AS Topic2,
C3.col1 AS Topic2,
C4.col1 AS Topic4
FROM
Parent P
LEFT JOIN
Child C1 ON P.Key = C1.FKey AND C1.ID = 1
LEFT JOIN
Child C2 ON P.Key = C2.FKey AND C2.ID = 2
LEFT JOIN
Child C3 ON P.Key = C3.FKey AND C3.ID = 3
LEFT JOIN
Child C4 ON P.Key = C4.FKey AND C4.ID = 4
You can use PIVOT too but I prefer the simpler self joins.
Take a look at PIVOT table functionality - e.g. http://www.help-sql.info/27/9/610208.html and http://blog.sqlauthority.com/2008/05/22/sql-server-pivot-table-example/
Although you will need to know the AssessmentId's before you can write the PIVOT
Database structure with two 1-n connections.
User table
==========
user_id
Attribute table
===============
attribute_id
user_id
attribute_name
Attribute_Value table
=====================
attribute_value_id
attribute_id
attribute_value
Is there a way that I can receive the data in the following row style:
user_id | firstname | lastname
---------------------------
1 | Simon | Smith
2 | John | Doe
Where name is the first attribute_name entry from the Attribute table and lastname the second.
Since you know the names of the values that you are looking for, a join will do the trick.
select
u.user_id,
a1.attribute_value as firstname,
a2.attribute_value as lastname
from User u
inner join Attribute a1
on u.user_id = a1.user_id
and a1.attribute_name = 'name'
inner join Attribute_Value v1
on a1.attribute_id = v1.attribute_id
inner join Attribute a2
on u.user_id = a2.user_id
and a2.attribute_name = 'lastname'
inner join Attribute_Value v2
on a2.attribute_id = v2.attribute_id
or so (did not run this). Use left joins if not everybody has a first or last name.
The only way you can do it with a dynamic number of columns is to use dynamic sql- use one sql statement to generate another by string concatenation.
Edit: I am not sure this is possible in mysql since there's not pivot command. Let me know if you want to see an example query from MS Sql I wrote. It is a similar data model, but there's just a lot more fields / joins.
Also I want to point out that you have a flaw in your design if attribute names wind up not being unique.
Take for example an application which has users, each of which can be in exactly one group. If we want to SELECT the list of groups which have no members, what would be the correct SQL? I keep feeling like I'm just about to grasp the query, and then it disappears again.
Bonus points - given the alternative senario, where it's a many to many pairing, what is the SQL to identify unused groups?
(if you want concrete field names:)
One-To-Many:
Table 'users': | user_id | group_id |
Table 'groups': | group_id |
Many-To-Many:
Table 'users': | user_id |
Table 'groups': | group_id |
Table 'user-group': | user_id | group_id |
Groups that have no members (for the many-many pairing):
SELECT *
FROM groups g
WHERE NOT EXISTS
(
SELECT 1
FROM users_groups ug
WHERE g.groupid = ug.groupid
);
This Sql will also work in your "first" example as you can substitute "users" for "users_groups" in the sub-query =)
As far as performance is concerned, I know that this query can be quite performant on Sql Server, but I'm not so sure how well MySql likes it..
For the first one, try this:
SELECT * FROM groups
LEFT JOIN users ON (groups.group_id=users.group_id)
WHERE users.user_id IS NULL;
For the second one, try this:
SELECT * FROM groups
LEFT JOIN user-group ON (groups.group_id=user-group.group_id)
WHERE user-group.user_id IS NULL;
SELECT *
FROM groups
WHERE groups.id NOT IN (
SELECT user.group_id
FROM user
)
It will return all group id which not present in user
I feel like an idiot asking this...
Table 1: users
id serial
person integer
username char(32)
Table 2:persons
id serial
name char(16)
Can I run a query that returns the name field in persons by providing the username in users?
users
1 | 1 | larry123
persons
1 | larry
2 | curly
SQL?
select name from persons where users.person=persons.id and users.username='larry123';
with the desired return of
larry
I have been doing it with two passes until now and think maybe a nested select using a join is what I need
1 | larry
It sounds like you're asking how to do a join in SQL:
SELECT
name
FROM
users JOIN persons ON (users.person = persons.id)
WHERE
users.username = 'larry123';
that is almost the query you wrote. All you were missing was the join clause. You could also do that join like this:
SELECT name
FROM users, persons
WHERE
users.person = persons.id
AND users.username = 'larry123';
I suggest finding a well-written introduction to SQL.