I'm using sqlite, I've setup three tables.
Table for list of skills this can be expand.
+----+----------+
| ID | Skills |
+----+----------+
| 1 | Swimming |
| 2 | Running |
| 3 | Boxing |
| 4 | Dancing |
| 5 | Singing |
+----+----------+
Table for availability of each person. 0 represents the person is not available.
+-------+-----+-----+-----+-----+-----+-----+-----+
| Names | SUN | MON | TUE | WED | THU | FRI | SAT |
+-------+-----+-----+-----+-----+-----+-----+-----+
| Mark | 0 | 1 | 1 | 1 | 1 | 1 | 0 | (MON-FRI)
| Robin | 0 | 1 | 1 | 1 | 1 | 1 | 0 | (MON-FRI)
| James | 0 | 0 | 1 | 1 | 1 | 1 | 1 | (TUE-SAT)
+-------+-----+-----+-----+-----+-----+-----+-----+
Table for each person skill possess. 1/0 is a boolean value.
+-------+----------+---------+--------+---------+---------+
| Names | Swimming | Running | Boxing | Dancing | Singing |
+-------+----------+---------+--------+---------+---------+
| Mark | 1 | 1 | 1 | 1 | 1 |
| Robin | 1 | 1 | 1 | 1 | 1 |
| James | 1 | 1 | 1 | 1 | 0 |
+-------+----------+---------+--------+---------+---------+
By using the tables above how could I achieved this result to sum each person's availability base on their skill.
Expected Results:
+----------+-----+-----+-----+-----+-----+-----+-----+
| Skills | SUN | MON | TUE | WED | THU | FRI | SAT |
+----------+-----+-----+-----+-----+-----+-----+-----+
| Swimming | 0 | 2 | 3 | 3 | 3 | 3 | 1 |
| Running | 0 | 2 | 3 | 3 | 3 | 3 | 1 |
| Boxing | 0 | 2 | 3 | 3 | 3 | 3 | 1 |
| Dancing | 0 | 2 | 3 | 3 | 3 | 3 | 1 |
| Singing | 0 | 2 | 3 | 3 | 3 | 3 | 0 |
+----------+-----+-----+-----+-----+-----+-----+-----+
I have query that count the headcount base on assigned letter code per day.
I've used 3 tables;
TABLE :status as st
+----------------+---------------+--------+
| ID | status_name | status_code | status |
+----+-------------+-------------+--------+
| 1 | Available | A | true |
+------------------+-------------+--------+
| 2 | HalfDay | H | true |
+------------------+-------------+--------+
| 3 | On Leave | OL | true |
+------------------+-------------+--------+
| 4 | Restday | R | true |
+------------------+-------------+--------+
| 5 | Vacation | V | true |
+------------------+-------------+--------+
TABLE : employees as e
+--------------+-------+-------+------+----------+
| EmployeeName | Site | Shift | Team | JobTitle |
+--------------+-------+-------+------+----------+
| Steve | Bldg1 | Night | N1 | Doctor |
+--------------+-------+-------+------+----------+
| Dave | Bldg1 | Night | N2 | Nurse |
+--------------+-------+-------+------+----------+
| Jack | Bldg1 | Night | N2 | Nurse |
+--------------+-------+-------+------+----------+
| Jacob | Bldg2 | Day | D1 | Doctor |
+--------------+-------+-------+------+----------+
| Noah | Bldg2 | Day | D2 | Nurse |
+--------------+-------+-------+------+----------+
| MAX | Bldg2 | Day | D2 | Nurse |
+--------------+-------+-------+------+----------+
TABLE : schedule as sc
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
| JobsType | Site | Shift | Team | SUN | MON | TUE | WED | THU | FRI | SAT |
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
| Doctor | Bldg1 | Night | N1 | A | H | A | A | OL | A | A |
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
| Nurse | Bldg1 | Night | N2 | A | H | H | A | A | A | A |
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
| Doctor | Bldg2 | Day | D1 | H | A | H | H | A | A | OL |
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
| Nurse | Bldg1 | Night | N2 | A | H | H | A | A | A | A |
+----------+-------+-------+------+-----+-----+-----+-----+-----+-----+-----+
By using this query:
SELECT st.status_name, st.status_code
, sum(sc.SUN = st.status_code) AS SUN
, sum(sc.MON = st.status_code) AS MON
, sum(sc.TUE = st.status_code) AS TUE
, sum(sc.WED = st.status_code) AS WED
, sum(sc.THU = st.status_code) AS THU
, sum(sc.FRI = st.status_code) AS FRI
, sum(sc.SAT = st.status_code) AS SAT
FROM status AS st
JOIN schedule AS sc ON st.status_code IN (sc.SUN, sc.MON, sc.TUE, sc.WED
, sc.THU, sc.FRI, sc.SAT)
JOIN employees AS e ON sc.JobsType = e.JobTitle AND sc.Site = e.Site
AND sc.Shift = e.Shift AND sc.Team = e.Team
GROUP BY st.status_name, st.status_code
ORDER BY st.status_name, st.status_code;
I achieved this result:
+--------------+-----+-----+-----+-----+-----+-----+-----+
| STATUS TYPES | SUN | MON | TUE | WED | THU | FRI | SAT |
+--------------+-----+-----+-----+-----+-----+-----+-----+
| Available | 5 | 4 | 4 | 5 | 5 | 6 | 5 |
+--------------+-----+-----+-----+-----+-----+-----+-----+
| HalfDay | 1 | 5 | 5 | 1 | 0 | 0 | 0 |
+--------------+-----+-----+-----+-----+-----+-----+-----+
| On Leave | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
+--------------+-----+-----+-----+-----+-----+-----+-----+
| Restday | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------+-----+-----+-----+-----+-----+-----+-----+
| Vacation | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------+-----+-----+-----+-----+-----+-----+-----+
-------------------------------------------------------------------
Now I'm having a hard time on how to work with a boolean value to reference.
Here are my tables;
TABLE: SkillList (1/0 = true/false)
+----------+--------+
| Skills | Status |
+----------+--------+
| Skill_1 | 1 |
+----------+--------+
| Skill_2 | 1 |
+----------+--------+
| Skill_3 | 1 |
+----------+--------+
| Skill_4 | 1 |
+----------+--------+
| Skill_5 | 0 |
+----------+--------+
TABLE: Skill Available (1/0 = true/false)
+----------+--------+---------+---------+---------+
| Username | Skill_1| Skill_2 | Skill_3 | Skill_4 |
+----------+--------+---------+---------+---------+
| Steve | 1 | 1 | 1 | 1 |
+----------+--------+---------+---------+---------+
| Dave | 1 | 0 | 1 | 0 |
+----------+--------+---------+---------+---------+
| Jack | 1 | 1 | 0 | 0 |
+----------+--------+---------+---------+---------+
| Jacob | 1 | 1 | 0 | 0 |
+----------+--------+---------+---------+---------+
Note: Zero represents users that doesn't have that skill.
TABLE: Attendance (1/0 = true/false)
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
| Username | Site | Shift | SUN | MON | TUE | WED | THU | FRI | SAT |
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
| Steve | Bldg1 | Night | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
| Dave | Bldg1 | Night | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
| Jack | Bldg2 | Day | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
| Jacob | Bldg1 | Night | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
+----------+-------+-------+-----+-----+-----+-----+-----+-----+-----+
Note: Zero represents restday.
By using the tables above how could I achieved this result that count available user per day base on there skill?
+-----------+-----+-----+-----+-----+-----+-----+-----+
| SkillList | SUN | MON | TUE | WED | THU | FRI | SAT |
+-----------+-----+-----+-----+-----+-----+-----+-----+
| Skill_1 | 4 | 3 | 2 | 2 | 3 | 3 | 3 |
+-----------+-----+-----+-----+-----+-----+-----+-----+
| Skill_2 | 3 | 3 | 1 | 1 | 2 | 2 | 2 |
+-----------+-----+-----+-----+-----+-----+-----+-----+
| Skill_3 | 2 | 2 | 1 | 0 | 2 | 1 | 1 |
+-----------+-----+-----+-----+-----+-----+-----+-----+
| Skill_4 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
+-----------+-----+-----+-----+-----+-----+-----+-----+
| Skill_5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+-----------+-----+-----+-----+-----+-----+-----+-----+
SQL databases are all about modelling relationships between data, and there are well established ways to do so. In this case, you have many users, each of which may have many skills, - a many to many relationship. The way to model this is known by many names, but I prefer junction table. Basically, instead of a table with a column for each skill and a row for each user, have a table of (skill id, user id) pairs with a row for each particular combination. If a user doesn't have a skill, no row with that particular combination exists.
Setting up some example tables from your data to demonstrate the idea:
CREATE TABLE SkillList(id INTEGER PRIMARY KEY, skill TEXT);
INSERT INTO SkillList VALUES
(1, 'Skill 1'), (2, 'Skill 2'), (3, 'Skill 3'), (4, 'Skill 4'), (5, 'Skill 5');
CREATE TABLE Attendance(id INTEGER PRIMARY KEY, username TEXT UNIQUE
, site TEXT, shift Text, SUN INTEGER, MON INTEGER
, TUE INTEGER, WED INTEGER, THU INTEGER, FRI INTEGER
, SAT INTEGER);
INSERT INTO Attendance VALUES
(1, 'Steve', 'Bldg1', 'Night', 1, 1, 1, 1, 1, 0, 0),
(2, 'Dave', 'Bldg1', 'Night', 1, 1, 0, 0, 1, 1, 1),
(3, 'Jack', 'Bldg2', 'Day', 1, 1, 1, 0, 0, 1, 1),
(4, 'Jacob', 'Bldg1', 'Night', 1, 0, 0, 1, 1, 1, 1);
CREATE TABLE SkillsAvailable(skill_id INTEGER REFERENCES SkillList(id)
, user_id INTEGER REFERENCES Attendance(id)
, PRIMARY KEY(skill_id, user_id)) WITHOUT ROWID;
INSERT INTO SkillsAvailable VALUES
(1, 1), (1, 2), (1, 3), (1, 4),
(2, 1), (2, 3), (2, 4),
(3, 1), (3, 2),
(4, 1);
will let you join the SkillList and Attendance tables together by putting SkillsAvailable in the middle:
SELECT sl.skill AS "Skill Name"
, ifnull(sum(a.SUN), 0) AS SUN
, ifnull(sum(a.MON), 0) AS MON
, ifnull(sum(a.TUE), 0) AS TUE
, ifnull(sum(a.WED), 0) AS WED
, ifnull(sum(a.THU), 0) AS THU
, ifnull(sum(a.FRI), 0) AS FRI
, ifnull(sum(a.SAT), 0) AS SAT
FROM SkillList AS sl
LEFT OUTER JOIN SkillsAvailable AS sa ON sl.id = sa.skill_id
LEFT OUTER JOIN Attendance AS a ON sa.user_id = a.id
GROUP BY sl.id
ORDER BY sl.skill;
Outer joins are used so that skills that aren't used by anyone still show up in the results, which are:
Skill Name SUN MON TUE WED THU FRI SAT
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
Skill 1 4 3 2 2 3 3 3
Skill 2 3 2 2 2 2 2 2
Skill 3 2 2 1 1 2 1 1
Skill 4 1 1 1 1 1 0 0
Skill 5 0 0 0 0 0 0 0
Besides making this sort of calculations more complex, your current database layout has other issues with the "Skills Available" table - adding a new skill means adding a new column, removing a skill you don't care about means either deleting that column - a very convoluted process in sqlite - or having unused ones hanging around wasting some space. It makes for a fragile, over complicated design. Better to play to the strengths of relational databases.
I have a table which is called Signer :
+--------------+----------+---------+--------+--------------+---------+-----------+
| Name | User | Order | Signed | CompanyName | Status | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
| Anders | aa | 1 | 0 | OvnAnd2 | 0 | 26650 |
| Peyman | pm | 2 | 1 | OvnAnd2 | 1 | 26650 |
| Siw Ericsson | se | 3 | 0 | OvnAnd2 | 0 | 26650 |
| test | test | 4 | 0 | OvnAnd2 | 0 | 26650 |
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 26652 |
| test | test | 2 | 1 | OvnAnd2 | 0 | 26652 |
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+
Goal:
As you can see I have 3 different InvoiceId's. For each InvoiceId, I would like to find a row with minimum order number that Status column's value is 0 and User column has to be se.
( It means, Show the current users related invoices which are ready to be signed based on his/her username, order, signed columns)
I came up with this T-SQL which works fine :
select * from Signer s1
where s1.User = 'se' and Order = (select min(Order) from Signer s2 where s2.InvoiceId = s1.InvoiceId and Signed = 0)
And the result:
+--------------+----------+---------+--------+--------------+---------+-----------+
| Name | User | Order | Signed | CompanyName | Status | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 26652 |
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+
I would like to convert this query from T-Sql to Linq or EntityFramework :
This is my solution:
var temp = from x in db.Signers
where x.User == Me.UserName &&
x.Signed == 0
group x by x.InvoiceId
into item
select new
{
item.Key,
item = item.Min(x => x.Order)
};
Which returns 3 rows which is wrong because Siw should see the related invoices that are ready to be signed by her. (It means the first row should not be in the list)
+--------------+----------+---------+--------+--------------+---------+-----------+
| Name | User | Order | Signed | CompanyName | Status | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
| Anders | aa | 1 | 0 | OvnAnd2 | 0 | 26650 |
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 26652 |
|Siw Ericsson | se | 1 | 0 | OvnAnd2 | 0 | 25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+
More info:
- As you can see in the first table, we have a special logic that someone can sign invoices out of order and Peyman is one of them.
- I don't want to use SqlQuery() method in Entityframework in order to execute t-sql queries.
I appreciate any help to find a solution for my goal.
Best regards
I think this is one of those situations where "let" come in handy:
var result = from s in Signers
let minToSign = Signers.Where(si =>
si.InvoiceId == s.InvoiceId && si.Signed == 0
).Min(si => si.Order)
where s.User == "se" && s.Order == minToSign
select s;
I am trying to figure out how to join two respective datarows into single datarow in dataset through Department column Name.
In provided dataset output i want to join Gastroenterology and Medical Gastroen(two datrows) through column name to single datarow (similar to Required Final dataset Output with Merged Rows).
Need Your ideas/help how it can be accomplished in asp.net and/or C#.
DataSet Output
Department Male Visit Female Visit Total Count
---------- ---------- ------------ -----------
Endocrinology 10 20 30
Gastroenterology 15 25 40
General Medicine 25 05 30
Medical Gastroen 30 20 50
Required Final Dataset Output with Merged Rows
Department Male Visit Female Visit Total Count
---------- ---------- ------------ -----------
Endocrinology 10 20 30
Gastroenterology 45 45 90
General Medicine 25 05 30
I think you must use joining for this in your database query. that would be better.
Table A
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
Table B.
+-----+---------------------+-------------+--------+
| OID | DATE | ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 | 3 | 3000 |
| 100 | 2009-10-08 00:00:00 | 3 | 1500 |
| 101 | 2009-11-20 00:00:00 | 2 | 1560 |
| 103 | 2008-05-20 00:00:00 | 4 | 2060 |
+-----+---------------------+-------------+--------+
SQL QUERY
SQL> SELECT ID, NAME, AMOUNT, DATE
FROM CUSTOMERS
INNER JOIN ORDERS
ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;
Resulted Table:
+----+----------+--------+---------------------+
| ID | NAME | AMOUNT | DATE |
+----+----------+--------+---------------------+
| 3 | kaushik | 3000 | 2009-10-08 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+----+----------+--------+---------------------+
I hope it will help you.
You can Do something like this.
DataTable _dataTable = new DataTable();
DataRow _dataRow1 = null;
_dataTable.TableName = "Products";
_dataTable.Columns.Add("ID",typeof(int));
_dataTable.Columns[0].AutoIncrementSeed = 1;
_dataTable.Columns[0].AutoIncrement = true;
_dataTable.Columns.Add("ProductsName");
_dataTable.Columns.Add("Price");
_dataRow1 = _dataTable.NewRow();
_dataRow1["ProductsName"] = "Sony Laptop";
_dataRow1["Price"] = "15000";
_dataTable.Rows.Add(_dataRow1);
DataRow _dataRow2 = null;
_dataRow2 = _dataTable.NewRow();
_dataTable.Rows.Add(_dataRow2);
_dataRow2["ProductsName"] = "LG Laptop";
_dataRow2["Price"] = "15000";
DataSet _dataSet = new DataSet();
_dataSet.Tables.Add(_dataTable);
I have two tables.
Menu
+----------------+----------------+
| menu_id | menu_desc |
+----------------+----------------+
| 1 | menu1 |
| 2 | menu2 |
| 3 | menu3 |
| 4 | menu4 |
| 5 | menu5 |
+----------------+----------------+
Rights
+----------+--------------+---------+
| Role_id | menu_id | Rights |
+----------+--------------+---------+
| 1 | 1 | 3 |
| 1 | 2 | 3 |
| 1 | 3 | 3 |
+----------+--------------+---------+
I want the output something like this,
+----------+------------------+------------+-----------+
| menu_id | menu_desc | Role_id | Rights |
+----------+------------------+------------+-----------+
| 1 | menu1 | 1 | 3 |
| 2 | menu2 | 1 | 3 |
| 3 | menu3 | 1 | 3 |
| 4 | menu4 | 1 | null |
| 5 | menu5 | 1 | null |
+----------+------------------+------------+-----------+
Is it possible?
This gives NULL for both Role_id and Rights
SELECT Menu.menu_id, Menu.menu_desc, Role.Role_id, Role.Rights
FROM Menu LEFT OUTER JOIN Role ON Menu.menu_id=Role.menu_id
ORDER BY Menu.menu_id
try below, if not getting required results then share problem:
SELECT m.menu_id, m.menu_desc, r.Role_id, r. Rights FROM Menu m LEFT JOIN `Rights` r ON m.menu_id=r.menu_id order by m.menu_id;
You have to use join:
select Menu.menu_id, menu_desc, Role_id, Rights.menu_id, Rights.Rights from Menu join Rights on Menu.menu_id=Rights.menu_id;