mysql query that outputs a table of data showing count - php

I have researched this and have not found the answer, so I thought someone here could shed some light. I'm trying to create a table of data returned showing the number of games picked for each user grouped by week numbers.
Database structure:
id | user | team | week_number
----+---------+-----------+-------------
1 | john | eagles | 1
2 | john | saints | 1
3 | harry | patriots | 1
4 | frank | cowboys | 1
5 | john | falcons | 2
6 | frank | cardinals| 2
Desired output:
week_number | frank | harry | john
------------+-------+-------+-------
1 | 1 | 1 | 2
2 | 1 | 0 | 1
I'll be using PHP to display the output.

The alternative to your desired output could be:
WEEK_NUMBER USER GAMES
1 frank 1
1 harry 1
1 john 2
2 frank 1
2 john 1
If this output could work for you, then you can run the following query:
select week_number,user,count(team) as games from table
group by week_number,user;

After banging my head in the wall, I got enlightenment and got the query finally. ;)
You could run this to achieve your desired output:
SELECT T.week_number,
IFNULL(SUM((CASE WHEN T.user = 'frank' THEN T.games END)),0) frank,
IFNULL(SUM((CASE WHEN T.user = 'harry' THEN T.games END)),0) harry,
IFNULL(SUM((CASE WHEN T.user = 'john' THEN T.games END)),0) john
FROM (select week_number,user,count(team) as games from table_name group by week_number,user) as T
GROUP BY week_number
DEMO

Related

Arrange rows based on given values in Laravel Eloquent

So I have these fields in my directors table
id, name, position, summary, deleted
This table has the following records
1 | John Doe | President | Some text | 0
2 | Mary Doe | Vice President | Some text | 0
3 | Hannah Doe | Treasurer | Some text | 0
4 | Ann Doe | Board | Some text | 0
5 | Mark Doe | Board| Some text | 0
6 | Johnny Doe | Secretary | Some text | 0
As of now, I can get them by using this code
$directors = Director::where('deleted',0)->get();
But how can I arrange based on my preferred values, this should arrange like this.
President, Vice President, Secretary, Treasurer, Board and if the position is blank this will be below the records of Board Position
1 | John Doe | President | Some text | 0
2 | Mary Doe | Vice President | Some text | 0
6 | Johnny Doe | Secretary | Some text | 0
3 | Hannah Doe | Treasurer | Some text | 0
4 | Ann Doe | Board | Some text | 0
5 | Mark Doe | Board| Some text | 0
The query will be like this
SELECT *
FROM `directors`
WHERE `deleted` = '0'
ORDER BY CASE position
WHEN "President" THEN 1
WHEN "Vice President" THEN 2
WHEN "Secretary" THEN 3
WHEN "Treasurer" THEN 4
WHEN "Board" THEN 5
ELSE 6 END, position;
Eloquent version;
return Director::where('deleted', 0)
->orderBy(
DB::raw(
'CASE position
WHEN "President" THEN 1
WHEN "Vice President" THEN 2
WHEN "Secretary" THEN 3
WHEN "Treasurer" THEN 4
WHEN "Board" THEN 5
ELSE 6
END, position'
)
)
->get();
If your database is small enough, and you are not against doing the sort in laravel after the query, as it may get slow with massive data, then here is one way to do it using the collection method sort().
$sortOrder = array_flip(['President', 'Vice President', 'Secretary', 'Treasurer', 'Board', '']);
$directors = Director::where('deleted',0)
->get()
->sort(function($prev,$next)use($sortOrder){
// Note: Flip $prev and $next around on this next line for opposite order
return $sortOrder[$prev->position] <=> $sortOrder[$next->position];
});

Mysql subtraction with 2 table or php

I have 2 table(example A and B)
A
-----------
id | name
-----------
1 | Bruce
2 | Peter
3 | Jack
4 | Alin
B
---------------------
id | status | A_id
---------------------
1 | 0 | 1
2 | 0 | 3
Subtraction with 2 table or php , I want to result is C
C
------------
id | name
------------
2 | Peter
4 | Alin
How can I do it?
Please give a try. Your C is a records that not shown from B right?
SELECT * From table a where id NOT IN (SELECT a_id from B)

Private Message System [Inbox Query]

I have a table called "message" and I want to show all talk between users (last message)
Table structure:
message_id | user_id | recipient_id | message | status | date
Example rows:
1 | 1 | 2 | Hello | 0 | 2016-03-26 12:00:00
2 | 2 | 1 | Hi | 0 | 2016-03-26 12:05:00
3 | 1 | 3 | Are you there? I want meet you! :P | 0 | 2016-03-26 12:20:00
4 | 1 | 2 | How are you? | 0 | 2016-03-26 12:10:00
5 | 2 | 1 | Fine :) | 0 | 2016-03-26 12:15:00
6 | 5 | 1 | Hi :D | 0 | 2016-03-26 15:00:00
So, result should be (for user_id == 1):
3 | 1 | 3 | Are you there? I want meet you! :P | 0 | 2016-03-26 12:20:00
5 | 2 | 1 | Fine :) | 0 | 2016-03-26 12:15:00
6 | 5 | 1 | Hi :D | 0 | 2016-03-26 15:00:00
First you sort by date, then you group by user_id
SELECT *
FROM
(
SELECT * from messages
WHERE `user_id`=1 or `recipient_id`=1
ORDER BY `date` DESC
) m
GROUP BY `user_id`
Result:
3 | 1 | 3 | Are you there? I want meet you! :P | 0 | 2016-03-26 12:20:00
5 | 2 | 1 | Fine :) | 0 | 2016-03-26 12:15:00
6 | 5 | 1 | Hi :D | 0 | 2016-03-26 15:00:00
sqlFiddle demo
I hope I will explain better than in my comment, here it goes:
First, you need to have logging system, so when user logins you save his ID to session.
Second, based on user that is logged you show all messages in "inbox" that he has with other users,select * from message where user_id = $_SESSION['id'], you can join tables and show it names from user and recipient
Third when he clicks on some chat with other person then you show all messages between them ordered by date based on user id and recipient_id
Would a query like select * from messages group by user_id order by date sort you? Fiddle demo.

MySql query to return only valid combinations of values

Can anyone help me write a mysql query that will look at a table in the m_sku column and see if m_sku has multiple records for a single value: for instance ABC has 3 records (Figure A). And if m_sku has multiple instance of a record check to see if the combination of m_sku & sku is different on any of them, then return that value. For instance, all these three records have different m_sku/sku combinations as seen in figure B.
Here is my main table...
Figure A.
id | sku | m_sku
---------------------------------------------
1 | 123 | ABC
2 | 123 | ABC
3 | 345 | ABC
4 | 456 | DEF
5 | 567 | EFG
6 | 678 | HIJ
7 | 567 | HIJ
8 | 890 | KLM
Here is what we are looking for...
Figure B.
1 | 123 | ABC
2 | 123 | ABC
3 | 345 | ABC
6 | 678 | HIJ
7 | 567 | HIJ
Here is only what I want to return...
id | m_sku
---------------------------------------------
1 | ABC
2 | HIJ
Thanks for any help you can provide.
SELECT m_sku FROM table GROUP BY m_sku HAVING COUNT(DISTINCT sku) > 1;
This will make sure that two or more rows with the same sku/m_sku pairs won't be returned by the query.
Not test but try this :
select distinct m_sku from your_table group by m_sku having count(sku) > 1

find top 3 values with an inner join

I have a table called users_preferred_zips that looks like this:
username | price | zip | program | active
-----------+---------+---------+-----------+---------
joe | 5 | 92108 | dog | 1
tom | 7 | 92108 | dog | 1
mary | 5 | 92108 | dog | 1
paul | 6 | 92108 | dog | 1
ron | 6 | 92108 | dog | 1
I have another table called users that looks like this
username | balance
-----------+----------
joe | 10
tom | 12
mary | 2
paul | 14
ron | 3
I need a query to pull AND sum the 3 highest values from the users_preferred_zips table where the username from the users table has a balance value greater than or equal to 5. I know i need to do some sort of inner join but my query below is not working. Here is the query i have:
SELECT SUM(price) AS SumOfTopValues
FROM (
SELECT users_preferred_zips . * , users.last_purchase, users.lesson_type, users.pref_acct_balance
INNER JOIN users ON ( users_preferred_zips.username = users.username )
WHERE users_preferred_zips.zip = '92108'
AND users_preferred_zips.program = 'dog'
AND users_preferred_zips.active = 1
AND users.pref_acct_balance >= '5'
ORDER BY price DESC
LIMIT 3
) AS sub
So the correct query would pull the following:
3 highest:
joe | 5
tom | 7
paul | 6
Sum of 3 highest values = 18
I feel like this should be pretty simple but i'm having a tough time! Thanks for your help
You can check this using:
SELECT SUM(price) AS SumOfTopValues
FROM users_preferred_zips
WHERE username IN (
SELECT username
FROM users
WHERE pref_acct_balance >= 5
)

Categories