Class attendance record format SQL Query [duplicate] - mysql

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
MySQL dynamic cross tab
I have student_record table
-------------------------------------------------------------------
student_id | semester | schoolyear| name | section |
-------------------------------------------------------------------
1 | 1st Semester| 2011-2012 | john | c21 |
2 | 1st Semester| 2011-2012 | eric | c21 |
3 | 1st Semester| 2011-2012 | mark | c21 |
and attendance table
-------------------------------------------------------------------
attendance_id | stud_id | week |
-------------------------------------------------------------------
1 | 1 | 02/04/2012 |
2 | 2 | 02/04/2012 |
3 | 3 | 02/04/2012 |
4 | 1 | 02/11/2012 |
5 | 2 | 02/11/2012 |
6 | 1 | 02/18/2012 |
7 | 2 | 02/18/2012 |
8 | 3 | 02/18/2012 |
And I want to achieve this output using sql.
-------------------------------------------------------------------
student_id | name | 02/04/2012 | 02/11/2012 | 02/18/2012 |
-------------------------------------------------------------------
1 | john | present | present | present |
2 | erik | present | absent | present |
3 | mark | present | present | present |
this is very vague to me, can anyone help?
I tried this, but didn't work.
Select week,
[02/28/2012],
[02/29/2012]
From attendance
group by student_id

Regardless of the database you are using, the concept of what you are trying to achieve is called "Pivot Table".
Here's an example for mysql:
http://en.wikibooks.org/wiki/MySQL/Pivot_table
Some databases have builtin features for that, see the links below.
SQLServer:
http://msdn.microsoft.com/de-de/library/ms177410.aspx
Oracle:
http://www.dba-oracle.com/t_pivot_examples.htm
You can always create a pivot by hand. Just select all the aggregations in a result set and then select from that result set.
Also check this link, you will get your answer provided by MGA...

Related

How to seperate an enum-value column to each value a bool column in MySQL [duplicate]

This question already has answers here:
MySQL: Pivot + Counting
(3 answers)
Closed 7 months ago.
I have a table:
+-----------+----------+
| articleId | category |
+-----------+----------+
| 1 | life |
| 1 | game |
| 2 | tech |
| 3 | life |
| ... | ... |
+-----------+----------+
Now I have to downgrade the paradigms of data, make them be flat and wide. Because they will be fed into an analysis enviroment which has no such data relationships. (actually, it's Elasticsearch)
Finally the selected data must be like this:
+-----------+------+------+------+
| articleId | game | life | tech |
+-----------+------+------+------+
| 1 | 1 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 1 | 0 |
| ... | | | |
+-----------+------+------+------+
Could you tell me how I can do that?
The categories field is enumrable, I can manually create each column.
You need to GROUP BY your articleId and check if your data exists:
SELECT t.`articleId`,
SUM(t.`category`='game') game,
SUM(t.`category`='life') life,
SUM(t.`category`='tech') tech
FROM test_test t
GROUP BY t.`articleId`
t.category='someText' will either return you 0 or 1 and then using SUM will give you your desired result.

SQL - Aggregate all EXCEPT group

Consider the following sample table from a soccer tournament (let's call this table matches)
+----------+---------+--------------+
| match_id | club_id | goals_scored |
+----------+---------+--------------+
| 1 | 1 | 1 |
| 1 | 2 | 0 |
| 2 | 1 | 1 |
| 2 | 3 | 1 |
| 3 | 1 | 0 |
| 3 | 4 | 2 |
| 4 | 2 | 2 |
| 4 | 3 | 4 |
| 5 | 2 | 4 |
| 5 | 4 | 0 |
| 6 | 3 | 1 |
| 6 | 4 | 1 |
+----------+---------+--------------+
The resulting table we want should give us each club's total goals scored AND goals conceded:
+---------+--------------+----------------+
| club_id | goals_scored | goals_conceded |
+---------+--------------+----------------+
| 1 | 2 | 4 |
| 2 | 6 | 4 |
| 3 | 6 | 4 |
| 4 | 3 | 5 |
+---------+--------------+----------------+
Getting goals scored is straight forward enough...
SELECT SUM(goals_scored),
club_id
FROM matches
GROUP BY club_id
but I am absolutely flummoxed as to how to get it for each team's opponents.
I could, of course, construct a pretty complex array of subqueries to get there. If this were application-side work I'd likely just stuff it in a loop and iterate over each club to get there, but my use case requires a SQL answer if possible. Any thoughts?
edit: also if anyone has any better ideas on how to title this question, I'm all ears - I'm not really sure exactly how to describe this problem in the first place.
We can use a self-join approach here:
SELECT
m1.club_id,
SUM(m1.goals_scored) AS goals_scored,
SUM(m2.goals_scored) AS goals_conceded
FROM matches m1
INNER JOIN matches m2
ON m2.match_id = m1.match_id AND
m2.club_id <> m1.club_id
GROUP BY
m1.club_id
ORDER BY
m1.club_id;
This approach brings the goals conceded by each club to the other club, for each match, into a single row. We then just aggregate by club to get the two sums.

Conditionally move MySQL data between rows in same table

Working in Redmine, I need to copy(not move) data from certain rows to other rows based on matching project id numbers with time entries.
I have included a diagram of the table "custom_values" and my understanding of the design below(CURRENT DATA):
+----+-----------------+---------------+-----------------+-------+
| id | customized_type | customized_id | custom_field_id | value |
+----+-----------------+---------------+-----------------+-------+
| 1 | Project | 1 | 1 | 01 |
| 2 | TimeEntry | 1 | 4 | 01 |
| 3 | Project | 2 | 1 | 02 |
| 4 | TimeEntry | 2 | 4 | 02 |
| 5 | Project | 3 | 1 | 03 |
| 6 | TimeEntry | 3 | 4 | |
| 7 | Project | 4 | 1 | 04 |
| 8 | TimeEntry | 4 | 4 | |
+----+-----------------+---------------+-----------------+-------+
At the risk of oversimplifying,
"id" = The primary key for each entry in custom_values
"customized_type" = Specifies which db table the row is referring to.
"customized_id" = Specifies the primary key for the db table entry previously specified in "customized_type".
"custom_field_id" = Specifies which custom field the row is referring to. Redmine admins can arbitrarily add and remove custom fields.
"value" = The data contained within the custom field specified by
"custom_field_id"
In my situation, the values listed in "value" are representing unique customer id numbers. The customer id numbers did not always get entered with each time entry. I need to copy the customer numbers from the project rows to the matching time entry rows. Each time entry has a project_id field.
So far, here is my mangled SQL query:
SELECT
custom_field_id,
custom_values.value AS 'CUSTOMER_NUMBER',
custom_values.customized_id AS 'PROJECT_ID_NUMBER',
custom_values.customized_type,
time_entries.comments AS 'TIME_ENTRY_COMMENTS'
FROM
redmine_tweaking.custom_values
LEFT JOIN
redmine_tweaking.time_entries ON custom_values.customized_id = time_entries.project_id
WHERE
custom_values.customized_type='Project' AND custom_values.custom_field_id=1;
The query I have so far allows me to see that I have the time entries connected properly to their matching projects, but that is all I have been able to figure out. So in other words, this SQL statement does not exactly solve my problem.
Plus, even if it did work, I think the way I laid it out looks like 200 lbs of bird poop. There must be a better/more optimized way to do this.
Any help would be greatly appreciated. I am relatively new and I have been pouring hours into solving this problem.
UPDATE:
Ok, here is the time_entries table:
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
| id | project_id | user_id | issue_id | hours | comments | activity_id | spent_on | tyear | tmonth | tweek | created_on | updated_on |
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
| 1 | 1 | 1 | 1 | .25 | test | 9 | 2015-11-04 | 2015 | 11 | 45 | 2015-11-04 08:18:12 | 2015-11-04 10:18:12 |
| 2 | 2 | 1 | 1 | .25 | test2 | 9 | 2015-11-04 | 2015 | 11 | 45 | 2015-11-04 09:18:12 | 2015-11-04 12:18:12 |
+----+------------+---------+----------+-------+----------+-------------+------------+-------+--------+-------+---------------------+---------------------+
As opposed to the original table that I first posted, the expected output would show this:
+----+-----------------+---------------+-----------------+-------+
| id | customized_type | customized_id | custom_field_id | value |
+----+-----------------+---------------+-----------------+-------+
| 1 | Project | 1 | 1 | 01 |
| 2 | TimeEntry | 1 | 4 | 01 |
| 3 | Project | 2 | 1 | 02 |
| 4 | TimeEntry | 2 | 4 | 02 |
| 5 | Project | 3 | 1 | 03 |
| 6 | TimeEntry | 3 | 4 | 03 |
| 7 | Project | 4 | 1 | 04 |
| 8 | TimeEntry | 4 | 4 | 04 |
+----+-----------------+---------------+-----------------+-------+

SQL INSERT INTO query syntax

I am trying to run an MySQL query to copy over data from an old table (ps__product_review/rate) to a new table (ps_product_comment/grade) based on review ID (id_product_comment). But I am a bit lost on the SQL query, this is what I have but keep getting errors.
INSERT INTO ps_product_comment [(grade)]
SELECT rate
FROM ps__product_review
[WHERE ps__product_review.id_product_comment=ps_product_comment.id_product_comment];
Can anyone help write the correct query?
Edit:Essentially I am trying to populate the Grade column in the new table below.
Old table (ps__product_review)
+--------------------+----------+-----+
| id_product_comment | Comment | Rate|
+--------------------+----------+-----+
| 1 | Good | 2 |
| 2 | Great | 5 |
| 3 | OK | 3 |
| 4 | Brill | 4 |
| 5 | OK | 3 |
| 6 | Average | 2 |
| 7 | Bad | 1 |
+--------------------+----------+-----+
New Table (ps_product_comment)
+--------------------+----------+-------+
| id_product_comment | Comment | Grade |
+--------------------+----------+-------+
| 1 | Good | |
| 2 | Great | |
| 3 | OK | |
| 4 | Brill | |
| 5 | OK | |
| 6 | Average | |
| 7 | Bad | |
+--------------------+----------+-------+
If you want to update table with data from another table, use UPDATE with JOIN
UPDATE ps_product_comment
JOIN ps__product_review
ON ps__product_review.id_product_comment = ps_product_comment.id_product_comment
SET ps_product_comment.grade = ps__product_review.rate;
Remove the square brackets and I think you are missing the JOIN(since you are using that in your where clause):
INSERT INTO ps_product_comment (grade)
SELECT rate
FROM ps__product_review inner join ps_product_comment on
ps__product_review.id_product_comment=ps_product_comment.id_product_comment;

Assistance with database design

I've got a excel sheet that contains all the employees that have worked for my company and is still working for us. It's a sheet of around 200 rows. Each row has basic info, like surname, name, position, qualification etc etc. 16 columns of basic info. Now, the tricky part is this. After the 16 columns, there are months (May-05 up to the present (Apr-12)). Under every month column, an employee either get's a 0 (contract), 1 (permanent), 2 (contract-terminated) or 3 (student).
What would be the best way to do this? I was thinking of 4 tables (listed below), where the one table determines permanently terminated people (for the sake of knowing who was on what type of employment).
MySQL Table: hr_employees
|-----------------|-------|----|----|----|
| employee_number | name | sur| etc| etc|
|-----------------|-------|----|----|----|
| 1 | Dave | F | xx | xx |
|-----------------|-------|----|----|----|
MySQL Table: hr_month
|----|--------|
| id | month |
|----|--------|
| 1 | May-05 |
| 2 | Jun-05 |
|----|--------|
MySQL Table: hr_status
|----|------|------|--------|
| id | e_no | date | status |
|----|------|------|--------|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 1 |
|----|------|------|--------|
MySQL Table: hr_terminated
|----|------|
| id | e_no |
|----|------|
| 1 | 1 |
| 2 | 1 |
|----|------|
I hope you guys understand what I want to achieve, otherwise, ask a question, and I'll answer as best I can! :)
Thanks.
Here is a design that simplifies your data entry and is more relational database like and less Excel like, insofar as it's normalized.
MySQL Table: hr_employee
|-----------------|-------|----|----|----|
| employee_number | name | sur| etc| etc|
|-----------------|-------|----|----|----|
| 1 | Dave | F | xx | xx |
|-----------------|-------|----|----|----|
| 2 | Bob | M | xx | xx |
|-----------------|-------|----|----|----|
MySQL Table: hr_employee_status
|-----------------|------------|------------|--------|
| employee_number | from_date | to_date | status |
|-----------------|------------|------------|--------|
| 1 | 2005-05-01 | 2005-08-31 | 3 |
|-----------------|------------|------------|--------|
| 1 | 2006-05-01 | 2010-02-28 | 0 |
|-----------------|------------|------------|--------|
| 2 | 2010-03-01 | 9999-12-31 | 1 |
|-----------------|------------|------------|--------|
Here you can see that Dave was hired on as a student from May '05 to August '05, then he came back in May '06 as a contract employee which he worked as until the end of February '10. Then on March 1, 2010 Bob was hired as permanent employee and he is still working (max collating date means "until further notice").
The great advantage of this design is that you only have to enter/edit data when something changes, not once a month for every employee that you have or have ever had. You can also see what your workforce looked like at any given date (not just by months!) with a very simple SQL query.