Manipulating/formatting database output - php

I've got a database query that outputs the data I need, but I'm not sure how to get it into the format I need (also need to get it into csv format, but need to get the output right first).
SELECT `user_id`, `assessment_name`, `question_id`, `question_type_id`, `answer`, `created_at` FROM answer WHERE `assessment_id` = 1
The output is like this (although with 30 rows per submission - just put three each here as an example):
11 Three Intelligences 31 6 4 7/22/08 11:30
11 Three Intelligences 40 4 4 7/22/08 11:30
11 Three Intelligences 41 6 5 7/22/08 11:30
10 Three Intelligences 31 6 3 7/22/08 14:54
10 Three Intelligences 40 4 4 7/22/08 14:54
10 Three Intelligences 41 6 4 7/22/08 14:54
12 Three Intelligences 31 6 4 7/29/08 10:31
12 Three Intelligences 40 4 4 7/29/08 10:31
12 Three Intelligences 41 6 4 7/29/08 10:31
What I need is to reformat this so that it can be used for data analysis, which means getting the data into a single row for each user_id and assessment_name and created_at
assessment_name, user_id, answer(for question 31), question_type_id(for question 31), answer(for question 40), question_type_id(for question 40), answer(for question 41), question_type_id(for question 41), created_at
Three Intelligences, 11, 6, 4, 4, 4, 6, 5, 7/22/08 11:30
Three Intelligences, 10, 6, 3, 4, 4, 6, 4, 7/22/08 14:54
Three Intelligences, 12, 6, 4, 4, 4, 6, 4, 7/29/08 10:31
Is this possible? If so, I also assume I can do it in php, but I don't know enough to figure out the 'while' loops necessary. It probably doesn't even need to produce a csv file output... if I can just get it properly formatted on the page I can copy/paste for this particular project.
Thanks
--EDIT--
Here's what I've got so far -- this will generate the semi-raw output of the data... I think what I need is just to figure out what loops within loops are required within the 'while' to get the desired output.
<?php
require_once '../connection.php';
// Create connection
$conn = new mysqli(localhost, $dbuser, $dbpass, $db);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$query_responses = "SELECT `user_id`, `assessment_name`, `question_id`, `question_type_id`, `answer`, `created_at` FROM answer WHERE `assessment_id` = 1";
$result_responses = $conn->query($query_responses);
if ($result_responses->num_rows > 0) {
// output data of each row
while($row = $result_responses->fetch_assoc()){
echo $row["created_at"]. ", " .$row["assessment_name"]. ", " .$row["user_id"]. "," .$row["question_id"]. "," .$row["question_type_id"]. "," .$row["answer"]. "<br />";
}
} else {
echo "0 results";
}
$conn->close();
?>

is it this what you looking for:
SELECT
`user_id`,
`assessment_name`,
CONCAT(
GROUP_CONCAT(
CONCAT(`question_type_id`, ', ', `answer`)
SEPARATOR ', ' ), ', ', `created_at`) AS RESULT
FROM answer
WHERE `assessment_id` = 1
GROUP BY `user_id`
ORDER BY `user_id`;
Sample
MariaDB []> SELECT
-> `user_id`,
-> `assessment_name`,
-> CONCAT(
-> GROUP_CONCAT(
-> CONCAT(`question_type_id`, ', ', `answer`)
-> SEPARATOR ', ' ), ', ', `created_at`) AS RESULT
-> FROM answer
-> -- WHERE `assessment_id` = 1
-> GROUP BY `user_id`
-> ORDER BY `user_id`;
+---------+---------------------+---------------------------------------------+
| user_id | assessment_name | RESULT |
+---------+---------------------+---------------------------------------------+
| 11 | Three Intelligences | 6, 4, 4, 4, 6, 5, 2016-01-01 00:00:00 |
| 12 | Three Intelligences | 6, 4, 6, 4, 6, 4, 6, 4, 2016-01-01 00:00:00 |
+---------+---------------------+---------------------------------------------+
2 rows in set (0.00 sec)
MariaDB []>
Please let me know if it works for you

Related

Php shuffle 2 unique numbers

I got a database with users and numbers.
I built a shuffle and tried to randomly give a user a number, that worked.
Now I have the issue that I want to give the user 2 random numbers with shuffle which shall be unique.
Main Code looks like this:
$numbers = range(0, $counts); // $counts are the number of users in my databse
$numbers2 = range(0, $counts);
shuffle($numbers);
shuffle($numbers2);
foreach($users as $user) {
# Starts from 1 if higher than 52
$uniqueRand = (array_pop($numbers)+$currentWeek) % 52 + 1;
$uniqueRand2 = (array_pop($numbers2)+$currentWeek) % 52 + 1;
# tried something like this but did
while($uniqueRand == $uniqueRand2) {
$numbers2 = range(0, $counts);
shuffle($numbers2);
$uniqueRand2 = (array_pop($numbers2)+$currentWeek) % 52+1;
}
...# Storing in database
}
Here a little sketch of the application
Users | numbers
__________________________
Frank | 14, 24
Tim | 21, 43
Tom | 52, 6
Hanz | 8, 3
Benjamin | 5, 1
West | 7, 6
Thompson | 4, 9
.....
The first line of numbers 14,21,52... stand for $numbers and the second line for $numbers2, I want to create unique random values which do not repeat themselves, but how do I check if the $number do not repeat in the same line and are still vertical unique.
So for instance would something like this be wrong:
Users | numbers
_________________________
Frank | 14, 14
Something like this would be wrong too:
Users | numbers
_________________________
Frank | 14, 24
Tim | 21, 14
Tom | 14, 6
Hanz | 8, 3
Benjamin | 5, 14
West | 14, 6
Thompson | 4, 9

MySQL query to get SUM and merged results from 3 tables

I am having 3 tables in my MySQL DB. The Tables and columns are like in sample below
Table User
id, name, dob, gross_salary
----------------------------------
1, test1, 12 Mar 90, 50000
2, test2, 10 Jan 85, 45000
Table Wage
ida, date, allowence_paid
------------------------------
1, 10 Jul 13, 12000
2, 10 Aug 13, 23000
2, 12 Aug 13, 1000
1, 15 Aug 13, 15000
Table Loan
id, date, loan_amount
--------------------------
2, 05 Jul 13, 500
1, 05 Aug 13, 2500
1, 06 Aug 13, 1200
I need these three tables merged in results for Aug 13 like
id, name, allowence_paid, loan_Amount, paid
--------------------------------------------
1, test1, 15000, 3700, 11300
2, test2, 24000, 0, 24000
SUM of two columns from two different tables joined to another table is required in my case.
Can I get help for the query? I have experimented as per MySQL JOIN with SUM and 3 tables and failed.
This seems to work:
select *, allowence_paid-loan_amount as paid
from
(
select User.id as UserId, User.name as UserName, sum(allowence_paid) as allowence_paid
from Wage join User on Wage.ida=User.id
and Wage.date between '2013-08-01 00:00:00' and '2013-08-31 23:59:00'
group by UserId
) W JOIN
(
select User.id as UserId, User.name as UserName, sum(coalesce(loan_amount,0)) AS loan_amount
from Loan right outer join User on Loan.id=User.id
and Loan.date between '2013-08-01 00:00:00' and '2013-08-31 23:59:00'
group by UserId
) L ON W.UserId = L.UserId
SQL fiddle here.

SQL query how to match 3 out of 4 results

I have searched a number of different items but I have not found any answers. Chances are I just don't know how to word this correctly.
Anyway, I have set up a system in PHP/SQL to allow instantaneous scanning of thousands of results. Each data entry has 4 numbers, and it can easily scan for entries that match all 4 of these numbers. What I am trying to achieve is to have the script search the database for entries that match exactly 3 out of the 4 entries with the other being incorrect, kind of like a lottery.
For example, we have the entries:
Steve - 1, 4, 10, 13
Bill - 3, 4, 10, 13
Tom - 1, 17, 20, 39
Jill - 1, 4, 13, 21
Jane - 5, 10, 13, 18
Now, I would scan based on the results 1, 4, 10, 13, and would like to return the following results, as these matched 3 of the 4 entries:
Bill - 3, 4, 10, 13
Jill - 1, 4, 13, 21
How would I achieve this?
Many thanks
EDIT: Sorry yes the table has the structure
Name - Number1 - Number2 - Number3 - Number4
So yes, stored as separate fields
You can do this by counting the matches and setting this equal to 3:
select t.*
from t
where (val1 in (1, 4, 10, 13) +
val2 in (1, 4, 10, 13) +
val3 in (1, 4, 10, 13) +
val4 in (1, 4, 10, 13)
) = 3;
In MySQL a TRUE boolean expression evaluates to 1. You can add these together to get the number of matches.

Combining multiple arrays in a timetable

I need a solution how to find all possible combinations of a schedule. There are courses on given dates that can vary by length. There is a given number of weeks. I need to find a solution to all possible combinations including all courses, with no overlapping.
$courses = array ("A", "B", "C", "D");
$duration = array (2, 3, 1, 2); // duration of $courses (in weeks)
$start_dates = array (
$courses[0] => array (1, 3, 5),
$courses[1] => array (1, 2, 5, 6),
$courses[2] => array (3, 4, 5, 9),
$courses[3] => array (1, 4, 8));
I would like to get all the possible combinations, e.g. this:
Week | Course
1 | A
2 | A
3 | C
4 | D
5 | D
6 | B
7 | B
8 | B
9 | -
10 | -
Second combination would be e.g. this:
Week | Course
1 | A
2 | A
3 | -
4 | C
5 | B
6 | B
7 | B
8 | D
9 | D
10 | -
The preferred output would be an array with week => course, like this:
$combinations = array (
0 => array (
1 => $courses[0],
2 => $courses[0],
3 => $courses[2],
4 => $courses[3],
...
),
1 => array (
1 => $courses[0],
2 => $courses[0],
4 => $courses[2],
5 => $courses[1],
6 => $courses[1],
7 => $courses[1],
...
)
);
I am really stuck with this problem. Thanks a lot for your help.

Seasonal Pricing for an Entity.

I am trying to manage seasonal prices for hotel rooms.
The only way that I can think of doing it would be to use:
A = Room Rate
B = Service Charge for room
Imagine that the table has a roomId column which is omited from below.
| DayDate |EndDate | A | B
-----------------------------------------------
| 2010/07/1 |2010/07/2 | 200 | 40
| 2010/07/3 |2010/07/4 | 150 | 40
| 2010/07/5 |2010/07/5 | 150 | 50
| 2010/07/6 |2010/07/7 | 200 | 50
| 2010/07/8 |2010/07/9 | 100 | 60
etc.. (table taken from another question).
The problem is: I don't want my seasons to be year specific.
Seasons for rooms shouldn't change year on year. I don't want my users to have to enter the seasonal information several times.
I am also going to have thousands of rooms, so I don't know a way to make this easily manageable.
I'm using mysql and php.
Start with a season table that defines the date ranges for the seasons. It should have a primary key field, say season_id. Then have another table to store room, price and season_id. The season_id is a foreign key to the season table.
Create Table Prices
(
MonthStart int not null
, DayStart int not null
, MonthEnd int not null
, DayEnd int not null
, A int not null
, B int not null
)
Insert Prices( MonthStart, DayStart, MonthEnd, DayEnd, A, B )
Select 7, 1, 7, 2, 200, 40
Union All Select 7, 3, 7, 4, 150, 40
Union All Select 7, 5, 7, 5, 150, 50
Union All Select 7, 6, 7, 7, 200, 50
Union All Select 7, 8, 7, 9, 100, 60
It should be noted that this approach presumes that the boundaries of the seasons are specific to the month and day regardless of year or circumstance. In addition, you'll have to decide how to handle leap year. Another approach which might be simpler is to simply enumerate every day of the year:
Create Table Prices
(
MonthStart int not null
, DayStart int not null
, A int not null
, B int not null
, Constraint PK_Prices Primary Key ( MonthStart, DayStart )
)
Insert Prices( MonthStart, DayStart, A, B )
Select 7, 1, 200, 40
Union All Select 7, 2, 200, 40
Union All Select 7, 3, 150, 40
Union All Select 7, 4, 150, 40
Union All Select 7, 5, 150, 50
Union All Select 7, 6, 200, 50
Union All Select 7, 7, 200, 50
Union All Select 7, 8, 100, 60
Union All Select 7, 9, 100, 60

Categories