I'm developing a system using WinForms C#.
I have two relational tables:
USER_PROFILE
| ID | NAME |
1 prof1
PERMISSIONS
| UPROFILE_ID | PERMISSION |
1 abc
1 acb
1 bca
I need to show the profiles on screen.
I dont know if it's the best fitting solution for my case, or how to implement it. My idea is to display in a DataGridView like this:
| Profile | Permission1 | Permission2 | Permission3 |
prof1 abc acb bca
Any suggestions?
Thanks in advance.
You can use 'case switch' to convert row into column. In actual select query you can construct column list dynamically.
Example:-
SQL> select id,name from user_profile;
ID NAME
1 U1
2 U2
SQL> select id,pname from per order by 1;
ID PNAME
1 A
1 B
2 C
SQL> select distinct u.name user_name, case when p.pname='A'then p.pname else null end permission1, case when p.pname='B' then p.pname else null end permission2 from user_profile u, per p where u.id=p.id order by 1;
USER_NAME PERMISSION1 PERMISSION2
-------------------- -------------------- --------------------
U1 A
U1 B
U2
Related
I am currently trying to do something like this with EF Core (fictional example):
-- Tables:
Entity1
Id |
UserId (nullable) |
GroupId (nullable) |
Group
Id | UserId
User
Id | Name
-- Sample Data:
Entity1
Id | UserId | GroupId
1 | null | 1
2 | 3 | null
3 | null | 2
User
Id | Name
1 | John
2 | Jimmy
3 | Jessica
Group
*Id | UserId *
1 | 1
2 | 2
The entity can either have a user or a group. Depending on which case, I want to sort for the user.name (if it has a user order directly for entity.user.name otherwise order by entity.group.user.name. When Ordering by user.name I want the results to be interleaved, so it would feel like, user is never null in Enitity1.
query.OrderBy(x => (x.User??x.Group.User).Name)
I wished this would order by the User.Name if an user exists on the entity and if not it would order by the group.name of the entity.
Expected results
I would expect that the Ids of Entity1 would be ordered like 2,3,1 (--> Jessica, Jimmy, John)
I found this: Order by Column1 if Column1 is not null, otherwise order by Column2
But I wasn't sure how to convert that to EF Core. I know I can do what I want when I do it with LINQ in memory, but I was wondering, if there is a chance to execute this OrderBy on the db.
I am loading some data into a repeater which is coming from two tables. The query against the second table is only selecting the MAX record though, and because of this complexity, I'm having to create a child repeater to then go off and find the Max record to display.
Table A: Activity List
ID | Activity
----+-----------------------
1 | Change Oil Filter
2 | Change brake fluid
3 | Change brake rotors
Table B: Mechanics Log
ID | ActivityID | Date | Mechanic | Comment
---+-------------+-------------+-------------------------------------------
1 | 1 | 2019-27-06 | John | Changed the oil filter
2 | 1 | 2019-26-06 | Sally | No oil filters in stock.
3 | 2 | 2019-20-06 | Sally | Brake fluid flushed.
As stated above, I can produce the following table using two repeaters (one inside the other) and it looks like this.
ActivityID | Date | Mechanic | Comment
-------------+-------------+-----------------------------------------
1 | 2019-27-06 | John | Changed the oil filter
2 | 2019-20-06 | Sally | Brake fluid flushed.
3 | | |
My question is: How can I produce the same table but using only one repeater and 1 T-SQL query? Is it possible? The reason being is that this is a very simple list (shortened for this demonstration) of the full list I have to enable for my mechanics work log, and when i start going to 100+ activities that can be done on a vehicle, the page loads quite slow; assuming because it has to fire off the 2nd repeater + code for each record it has bound.
I also apologize I do not yet have a 'starting point' for you to work with, as nothing I have created has come even close to producing the result in one query. I am having trouble working out how I combine the first part of the query with the MAX(Date) of the 2nd table. Hoping for some assistance from the community to help.
You can use the below query to get the desired result -
Sample Data
Declare #ActivityList Table
(ID int, Activity varchar(100))
Insert into #ActivityList
values
(1 , 'Change Oil Filter' ),
(2 , 'Change brake fluid' ),
(3 , 'Change brake rotors' )
Declare #MechanicsLog Table
(ID int, ActivityID int, [Date] Date, Mechanic varchar(20), Comment varchar(50))
Insert into #MechanicsLog
values
(1 , 1 , '2019-06-27' , 'John' , 'Changed the oil filter' ),
(2 , 1 , '2019-06-26' , 'Sally' , 'No oil filters in stock.' ),
(3 , 2 , '2019-06-20' , 'Sally' , 'Brake fluid flushed.' )
Query
;With cte as
(select ActivityID, Max([Date]) [date] from #MechanicsLog ml
Group By ActivityID
)
Select al.ID, al.Activity, cte.[Date], Mechanic, Comment
from cte inner join #MechanicsLog ml
on cte.ActivityID = ml.ActivityID and cte.[date] = ml.[Date]
right join #ActivityList al on al.ID = ml.ActivityID
order by ID
If you add use the ROW_NUMBER function to add a sequence to each activity ID, you can then filter that to only get the most recent for each activity ID.
select ActivityID, Date, Mechanic, Comment
from
(
select *, ROW_NUMBER() OVER (PARTITION BY ActivityID order by Date desc) RowNumber
from MechanicsLog
) q1
where RowNumber = 1
This gives you the "MAX" record for each ActivityID but with the rest of the record, so you can join to the Activity List table if you want.
select
act.ActivityID, Max(log.[Date]) as [Date]
from
ActivityList act
inner join
MachineLog log on log.ActivityID = act.ActivityID
Group by
act.ActivityID
Table 1: ABC table 2: PQR
code|Name|Amount code|Name|Amount
----+----+----- ----+----+------
1 | A | 1000 1 | A | 1000
2 | B | 2000 2 | B | 2000
3 | C | 4000
4 | D | 1000
data in table 2 is insert from data based on table 1, now by pressing a button named "Remaining" i want to show data that is not present in table 2, to know which tuples i have missed to fill from table 1. How can i do it?
If the fields in the 2 tables are exactly the same and in the same order?
But you can't bother to put those fields in the SQL?
Then you could also use an EXCEPT
SELECT * FROM ABC
EXCEPT
SELECT * FROM PQR;
And if you're not certain that the fields are in the same order?
Then list them in the SQL.
That has also the benefit that the SQL will probably still work when one of the tables is altered.
SELECT [code], [Name], [Amount] from ABC
EXCEPT
SELECT [code], [Name], [Amount] FROM PQR;
It filters out the PQR records that are exactly the same as those found in ABC.
But normally, the methods that Tim Biegeleisen showed are more commonly used.
This answer assumes that you want to find all records in the first table which are not already present in the second table. One option uses a left join:
SELECT t1.*
FROM ABC t1
LEFT JOIN PQR t2
ON t1.code = t2.code AND t1.Name = t2.Name AND t1.Amount = t2.Amount
WHERE t2.code IS NULL;
We could also phrase this using EXISTS:
SELECT t1.*
FROM ABC t1
WHERE NOT EXISTS (SELECT 1 FROM PQR t2
WHERE t1.code = t2.code AND t1.Name = t2.Name AND
t1.Amount = t2.Amount);
I'm trying to insert values into some table with this code using C# and SQL:
string query1 = "select PlayerID from Table1";
string query2 = "select GameID from Table2";
string q = "insert into Table3 (PlayerID, GameID) values(" + query1 + "," + query2 + ")";
Is it possible?
Edit:
I have 3 tables:
playersTbl - with auto increment id (primary key)
gameTbl - with auto increment id (primary key)
JoinTbl
When the game is starting, the user can register some players to the same game, so
in the same game lets say there are 4 players.
When I'm adding those 4 players the playersTbl will look like:
ID | first name|
----------------
1 | p1 |
2 | p2 |
3 | p3 |
4 | p4 |
and the gameTbl will look like:
ID | Date | Hour|
-----------------
1 | | |
So what I'm trying to do is the Table3 will look like:
PlayerID | GameID|
------------------
1 | 1 |
2 | 1 |
3 | 1 |
4 | 1 |
Now when I'm starting a new game with one player
I'm adding the player to the playersTbl, and the game to the gameTbl, but now the third table will look like
PlayerID | GameID|
------------------
1 | 1 |
2 | 1 |
3 | 1 |
4 | 1 |
5 | 2 |
to be more clear, I don't want that players which are registered in the second game will be in the first game..
use INSERT INTO..SELECT statement,
INSERT INTO Table3(PlayerID, GameID)
SELECT a.PlayerID, b.GameID
FROM Table1 a CROSS JOIN Table2 b
what the query does is it produces cartesian product from both tables.
Consider The following example,
Table1
PlayerID
========
1
2
3
Table2
GameID
=======
10
11
12
when the query below is executed,
SELECT a.PlayerID, b.GameID
FROM Table1 a CROSS JOIN Table2 b
it produces the following result,
PlayerID GameID
========= ======
1 10
1 11
1 12
2 10
2 11
2 12
3 10
3 11
3 12
You should be able to utilize the INSERT INTO SELECT method, like this:
INSERT INTO Table3 (PlayerID, GameID) SELECT Table1.ID, Table2.ID FROM Table1, Table2
I have a linq query that joins two tables (no relation in the actual db)
the relation is:
Companies 1 - n Phones
var miniCompanies =
(from companies in db.Companies
join phones in db.Phones on companies.Id equals phones.CompanyId
select new
{
companies.Name,
phones.Phone,
}).ToList().Distinct();
this returns something like:
----------------------------
company1 | 12345 |
----------------------------
company1 | 23456 |
----------------------------
company2 | 43242 |
----------------------------
company2 | 34234 |
----------------------------
company2 | 65442 |
----------------------------
i need to get only the fisrt in Phones table not everything
how to do that?
Edit:maybe i wasn't clear about what want sorry for that.
i ment:
----------------------------
company1 | 12345 |
----------------------------
company2 | 43242 |
----------------------------
i want the first phone for each company
You can use GroupBy:
var miniCompanies =
(from companies in db.Companies
join phones in db.Phones on companies.Id equals phones.CompanyId
select new
{
companies.Name,
phones.Phone,
}).GroupBy(c=>c.Name).Select(c=>c.FirstOrDefault()).ToArray();
1 You can try with First operator
(from companies in db.Companies
join phones in db.Phones on companies.Id equals phones.CompanyId
select new
{
phones.Phone,
}).First();
Link : http://msdn.microsoft.com/fr-fr/library/vstudio/system.linq.queryable.first.aspx
2 You can also use FirstOrDefault
Link : http://msdn.microsoft.com/fr-fr/library/vstudio/system.linq.queryable.firstordefault.aspx
3 You can also use Take(1);
Link : http://msdn.microsoft.com/fr-fr/library/vstudio/bb300906.aspx
I would use the following:
var miniCompanies =
(from companies in db.Companies
join phones in db.Phones on companies.Id equals phones.CompanyId
select new
{
companies.Name,
phones.Phone,
}).ToList().Distinct().FirstOrDefault();
The 'FirstOrDefault()' method will return the first item in the collection. If the collection contains no elements, the default object will be returned. For nullable types, this will be a 'null' object. This is a good way to prevent your application from failing due to an exception related to an empty collection.