Sql- ordering based on two columns in a table - c#

consider a database having
checkID record_number data Order_number
a 0 1 2
a 1 2 0
a 2 3 1
a 3 4 3
Find a query which fetches the records according to Order_number column i.e.procedure should return data :
having record _number 2 then
having record _number 0 then
having record _number 1 then
having record _number 3
Is there any join or other query for this?

SELECT *
FROM tablename
ORDER BY CASE WHEN record_number = 2 THEN 0 ELSE 1 END, record_number;
SQL Fiddle Demo
This will give you your data in the following order:
| CHECKID | RECORD_NUMBER | DATA | ORDER_NUMBER |
-------------------------------------------------
| a | 2 | 3 | 1 |
| a | 0 | 1 | 2 |
| a | 1 | 2 | 0 |
| a | 3 | 4 | 3 |

select *
from YourTable
order by
case record_number
when 2 then 1
when 0 then 2
when 1 then 3
when 3 then 4
end

You can use CASE WHEN on this situation.;
SELECT *
FROM tbl
ORDER BY CASE record_number
WHEN 2 THEN 1
WHEN 0 THEN 2
WHEN 1 THEN 3
WHEN 3 THEN 4
END
Here is SQL Fiddle DEMO.
| CHECKID | RECORD_NUMBER | DATA | ORDER_NUMBER |
-------------------------------------------------
| a | 2 | 3 | 1 |
| a | 0 | 1 | 2 |
| a | 1 | 2 | 0 |
| a | 3 | 4 | 3 |

The best solution would be to create additional table for sorting checks, like this:
record_number sort_seq
2 1
0 2
1 3
3 4
then join it with your table
select c.*
from check as c
join sortSeq as s on c.record_number=s.record_number
order by s.sort_seq

SELECT *
FROM tablename
ORDER BY Order_number

Related

How to simplify query boolean data in sqlite?

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.

Oracle Recursion

I want list all SOURCE_ID if the source has destination, the query below not work probably !!
select SOURCE_ID,
LINK_TYPE,
DESTINATION_ID
from LINK_TABLE
where link_table.link_type=1
and link_table.destination_is_deleted=0
START WITH link_table.source_id='100'
CONNECT BY PRIOR link_table.source_id=link_table.destination_id
Sample data
SOURCE_ID | DESTINATION_ID | LINK_TYPE| DESTINATION_IS_DELETED|
----------|-----------------|----------|-----------------------|
100 | 1500 | 1 | 0 |
100 | 1200 | 1 | 0 |
100 | 1300 | 1 | 1 |
1500 | 600 | 1 | 0 |
1500 | 700 | 1 | 0 |
700 | 88 | 1 | 0 |
Assuming you want to walk the hierarchy from the root nodes to the leaves this is what you need:
select SOURCE_ID,
LINK_TYPE,
DESTINATION_ID
from LINK_TABLE
where link_table.link_type=1
and link_table.destination_is_deleted=0
START WITH link_table.source_id='100'
CONNECT BY PRIOR link_table.destination_id = link_table.source_id
/
It's just a matter of swapping the referenced columns in the CONNECT BY PRIOR clause. Unfortunately the Oracle syntax is not intuitive here: I've been using it for over twenty years and I still have to test a query to make sure I've got them the right way round :)
I changed the query structure to solve the issue.
select SOURCE_ID,DESTINATION_ID,link_table.source_class,link_table.linktype,link_table.destination_class
from LINK_TABLE
where (link_table.source_id in( select link_table.DESTINATION_ID from link_table where link_table.source_id='100'and link_table.linktype=1 and link_table.destination_isdeleted=0 ))
and (link_table.linktype=1) or (link_table.source_id='100')

Linq query require for a join

I am having two below tables. I need to unassigned rights for group 3 and my sql query is like below
select rightname
from IB_Right_Master
where id
not in (select RightID from IB_Group_Rights where GroupID = '3');
Table : RightMaster
ID | RightName | RightGroupName |
----------------------------------------------
1 | Test1 | test1 |
----------------------------------------------
2 | Test2 | test2 |
----------------------------------------------
3 | Test3 | Test3 |
----------------------------------------------
4 | Test4 | Group Test4 |
----------------------------------------------
Table : Group Rgihts
ID | RightID | GroupID |
----------------------------------------------
1 | 1 | 1 |
----------------------------------------------
2 | 1 | 2 |
---------------------------------------------
3 | 2 | 3 |
---------------------------------------------
4 | 3 | 4 |
---------------------------------------------
5 | 1 | 3 |
---------------------------------------------
Desired Output : for a group id 3
RightID | RightName |
-----------------------------
3 | Page Access |
------------------------------
4 | Delete Group |
-----------------------------
Try this query
from e in context.IB_Right_Master
where !(from e2 in context.IB_Group_Rights
where e2.GroupID == 3
select e2.RightID).ToList().Contains(e.id)
select e;

Insert DataTable into nested TreeView c#

I got a database like
CID | CName | CParent
--------+---------+---------
1 | A | 0
2 | b | 1
3 | c | 1
4 | d | 1
5 | e | 2
6 | f | 3
7 | g | 6
8 | h | 2
9 | i | 8
I want to represent this data into a nested treeview connecting each entity to its father which is the CParent.
What is the best way to get this treeview and how?

how to dynamically create multiple select statement and store it in a datatable

the case here is the number of columns i would like to store to the datatable depends on the number of available data. i would need a multiple select statements to collect all the data.
select test_result.stud_id,test_info.max_score,
test_result.test_score
from test_result left join test_info
on test_result.test_info_id = test_info.test_info_id
where test_info.test_type_id = 1 and test_info.test_num = 1;
i would have to repeat this code over and over again until the test_num reaches the current maximum count. i was thinking of looping this code while storing it to the datatable.this is what i would like the datagridview would display.
|Quiz Number | Quiz#1 | Quiz #2 | Quiz #3 | Quiz #4 | Quiz #5 |
|Max score | 20 | 25 | 30 | 15 | 15 |
|student 1 | 18 | 22 | 25 | 12 | 14 |
|student 2 | 19 | 20 | 25 | 11 | 13 |
|student 3 | 20 | 24 | 20 | 12 | 11 |
the display of data would be in rows. so each row would require a different select statement in order to display the required data.
Something like below will woek for you
select
test_result.stud_id,
max(case when test_result.test_info_id =1 then test_result.test_score end) as quiz_1,
max(case when test_result.test_info_id =2 then test_result.test_score end) as quiz_2,
max(case when test_result.test_info_id =3 then test_result.test_score end) as quiz_3,
.
.
.
from test_result left join test_info
on test_result.test_info_id = test_info.test_info_id
where test_info.test_type_id = 1 and test_info.test_num = 1
group by test_result.stud_id;

Categories

Resources