473,786 Members | 2,806 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How do I do this query?

I wish I knew what this was called, and I could have made a more sensible
subject. For that matter, I knew what it was called, I could have googled it!

Anyway, let's I have a table with name, class, grade.

joe bio a
jill chem b
john psych b
john chem a
jill pysch a

and I want to display the results as

name bio psych chem
joe a - -
jill - a b
john - b a

Is there a way to do this with sql? How about sql with php?

Thanks much!

Manny
--
manny@don't spam on me
Jan 12 '06 #1
14 1757
"manny" <ma***@dontspam onme.net> wrote in message
news:lv******** *************** *********@4ax.c om...
I wish I knew what this was called, and I could have made a more sensible
subject. For that matter, I knew what it was called, I could have googled it!
Anyway, let's I have a table with name, class, grade.

joe bio a
jill chem b
john psych b
john chem a
jill pysch a

and I want to display the results as

name bio psych chem
joe a - -
jill - a b
john - b a

Is there a way to do this with sql? How about sql with php?


This is called a "pivot" table. Your data row [class] becomes multiple
columns, one for each discrete data value contained in your original
[class].

And, yes, it can be done in MySQL flavor of sql although it is awkward.
Google on "pivot" and "mysql".
The query can be easy if you have a small fixed list of [class] values which
your example suggests might be the case. True pivot table facilities (which
MySQL lacks!) can manage arbitrary data in the pivot field.

The body of your "pivot" table - the [grade]s - needs to be aggregated in
some way. Each each [name]/[class] intersection can only contain a single
value. One might assume, for example, that Jill will have several bio
grades and these need to be summarized. You would show a single grade
average (or max, or min) value.

It would probably be easier to an initial query and then re-arrange the
table with php.

What os environment are you using? Interestingly, Microsoft Jet flavor of
sql has a PIVOT command that is perfect for this. This means that if you
can create a linked MySQL table in Access you can then avail yourself to
this facility. We frequently use Excel as a front end to MySQL and get to
use Excel's very excellent pivot table function with an initial query
against MySQL.

But, alas! AFAIK - MySQL doesn't have PIVOT which means you have to work
harder at it.

Someone can shout back at me if I am missing something.
Thomas Bartkus


Jan 12 '06 #2

"manny" <ma***@dontspam onme.net> wrote in message
news:lv******** *************** *********@4ax.c om...
I wish I knew what this was called, and I could have made a more sensible
subject. For that matter, I knew what it was called, I could have googled it!
Anyway, let's I have a table with name, class, grade.

joe bio a
jill chem b
john psych b
john chem a
jill pysch a

and I want to display the results as

name bio psych chem
joe a - -
jill - a b
john - b a

Is there a way to do this with sql? How about sql with php?


I almost forgat "crosstab" table!
Both "pivot" and "crosstab" are used to describe what you are trying to
achieve.

Thomas Bartkus
Jan 12 '06 #3
["Followup-To:" header set to comp.lang.php.]
manny wrote:
I wish I knew what this was called, and I could have made a more sensible
subject. For that matter, I knew what it was called, I could have googled it!
Not sure if it's useful but, if I'm not mistaken,
Excel calls it a "pivot table".
Anyway, let's I have a table with name, class, grade.

joe bio a
jill chem b
john psych b
john chem a
jill pysch a

and I want to display the results as

name bio psych chem
joe a - -
jill - a b
john - b a

Is there a way to do this with sql?
I don't know. Maybe someone on mailing.databas e.mysql will answer you.
.... you may want to try posting to comp.databases. mysql or some
newsgroup about sql in general.
Followups set to comp.lang.php because my answer is strictly php.
How about sql with php?


Easy :)
With no need for sql at all.
Hope I'm not doing your homework ...


<?php
$data = array(
array('joe', 'bio', 'a'),
array('jill', 'chem', 'b'),
array('john', 'psych', 'b'),
array('john', 'chem', 'a'),
array('jill', 'psych', 'a'),
); /* could come from a database */

/* restructure data and get classes */
$new_data = array();
$classes = array();
foreach ($data as $val) {
if (!in_array($val[1], $classes)) $classes[] = $val[1];
if (isset($new_dat a[$val[0]][$val[1]])) {
$new_data[$val[0]][$val[1]] .= $val[2];
} else {
$new_data[$val[0]][$val[1]] = $val[2];
}
}
sort($classes);

header('Content-Type: text/plain'); /* I'm lazy */

/* print header */
echo "name\t";
echo implode("\t", $classes);
echo "\n";

/* print data rows */
foreach ($new_data as $k=>$v) {
echo $k, "\t";
foreach ($classes as $class) {
echo isset($v[$class])?$v[$class]:'-', "\t";
}
echo "\n";
}
?>

--
Mail to my "From:" address is readable by all at http://www.dodgeit.com/
== ** ## !! ------------------------------------------------ !! ## ** ==
TEXT-ONLY mail to the whole "Reply-To:" address ("My Name" <my@address>)
may bypass my spam filter. If it does, I may reply from another address!
Jan 12 '06 #4
"manny" <ma***@dontspam onme.net> wrote in message
news:lv******** *************** *********@4ax.c om...
Is there a way to do this with sql? How about sql with php?


I've seen a few articles on achieving a pivot table result with MySQL, and
they made my head hurt.
http://www.wellho.net/mouth/59_MySQL-Pivot-tables.html
http://en.wikibooks.org/wiki/Program...QL/Pivot_table
http://www.onlamp.com/pub/a/onlamp/2...crosstabs.html

Joe Celko's "SQL for Smarties" also gives several options for producing
crosstabs purely in SQL.

In some cases, it may be the quickest solution to get the raw data out of
the database and into your application code, and then massage it until you
get the result you want.

Regards,
Bill K.
Jan 12 '06 #5
Pedro Graca, Bill Karwin, Thomas Bartkus, and others wrote:

....various solutions and ideas.

Thanks to all. I've used pivot tables/crosstabs in Excel before, but somehow
didn't connect that this was what I wanted out of my sql query. I need to do
this directly on the server and not with results downloaded/manipulated in
Excel.

BTW, Pedro's Php code works great and that will probably be the method that I
use.

Again, much appreciation.

Manny

--
manny@don't spam on me
Jan 13 '06 #6

"manny" <ma***@dontspam onme.net> wrote in message
news:lv******** *************** *********@4ax.c om...
I wish I knew what this was called, and I could have made a more sensible
subject. For that matter, I knew what it was called, I could have googled
it!

Anyway, let's I have a table with name, class, grade.

joe bio a
jill chem b
john psych b
john chem a
jill pysch a

and I want to display the results as

name bio psych chem
joe a - -
jill - a b
john - b a

Is there a way to do this with sql? How about sql with php?

Thanks much!

Manny


You can create an associative array in PHP then use the values as you want,
ie. print them to a file or an HTML table etc.

note: the example code needs more/better error checking, comments
<?
// assumes a mysql db with a "grades" table containing name, class, and
grade columns

$conn = mysql_connect(" localhost", "my_mysql_usern ame",
"my_mysql_passw ord");
if (!$conn || !mysql_select_d b("my_mysql_db" )) { echo mysql_error(); exit; }

$sql = "SELECT DISTINCT name FROM grades order by name";
$result = mysql_query($sq l);

if (!$result || mysql_num_rows( $result) == 0) { echo mysql_error(); exit; }
$grades = array();
while ($row = mysql_fetch_row ($result)) {
$grades[$row[0]] = array();
}
mysql_free_resu lt($result);

foreach (array_keys($gr ades) as $name) {
$sql = "SELECT class, grade FROM grades where name=\"$name\"" ;
$result = mysql_query($sq l);
if (!$result) { echo mysql_error(); exit; }
while ($row = mysql_fetch_ass oc($result)) {
$grades[$name][$row['class']] = $row['grade'];
}
}
mysql_free_resu lt($result);

print_r($grades );
?>

prints:
Array (
[jill] => Array ( [chem] => b [psych] => a )
[joe] => Array ( [bio] => a )
[john] => Array ( [psych] => b [chem] => a )
)

You could also define defaults:

$classes = array('chem', 'bio', 'psych');

foreach ($classes as $class) {
foreach (array_keys($gr ades) as $name) {
$grades[$name][$class] = (
isset($grades[$name][$class])
&&
preg_match("/^(?:[a-f]-?|-)$/", $grades[$name][$class])
)
? $grades[$name][$class] : '-' ;
ksort($grades[$name]);
}}

print_r($grades );

Prints:

Array (
[jill] => Array ( [bio] => - [chem] => b [psych] => a )
[joe] => Array ( [bio] => a [chem] => - [psych] => - )
[john] => Array ( [bio] => - [chem] => a [psych] => b )
)
Rich
Jan 13 '06 #7
Rich wrote:
<snip>
$sql = "SELECT DISTINCT name FROM grades order by name";
$result = mysql_query($sq l);
1 query
if (!$result || mysql_num_rows( $result) == 0) { echo mysql_error(); exit; } ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
nice construct!
$grades = array();
while ($row = mysql_fetch_row ($result)) {
$grades[$row[0]] = array();
}
mysql_free_resu lt($result);

foreach (array_keys($gr ades) as $name) {
$sql = "SELECT class, grade FROM grades where name=\"$name\"" ;
$result = mysql_query($sq l);
a whole bunch of queries!!!
Don't do this if possible.
Avoid doing queries inside loops.

If your table has 1000 names you'd do 1001 queries (one for the
DISTINCT names and 1000 for the classes)
if (!$result) { echo mysql_error(); exit; }
while ($row = mysql_fetch_ass oc($result)) {
$grades[$name][$row['class']] = $row['grade'];
}
}
mysql_free_resu lt($result);
Why isn't this inside the foreach loop too?
print_r($grades );
?>

prints:
Array (
[jill] => Array ( [chem] => b [psych] => a )
[joe] => Array ( [bio] => a )
[john] => Array ( [psych] => b [chem] => a )
)


Yes, it gets the desired results, but at a *very large* cost!

<snip>

--
Mail to my "From:" address is readable by all at http://www.dodgeit.com/
== ** ## !! ------------------------------------------------ !! ## ** ==
TEXT-ONLY mail to the whole "Reply-To:" address ("My Name" <my@address>)
may bypass my spam filter. If it does, I may reply from another address!
Jan 14 '06 #8

"Pedro Graca" <he****@dodgeit .com> wrote in message
news:sl******** ***********@ID-203069.user.ind ividual.net...

<snip>
If your table has 1000 names you'd do 1001 queries (one for the
DISTINCT names and 1000 for the classes)
You're right. If there were 1000 names you should loop through the results
of 1 query. But there were only 5.

If there were 1000 names, the structure of the table given would make even
less sense (if that's possible)

Yes, it gets the desired results, but at a *very large* cost!

<snip>


I took a few minutes out of my busy day to give the OP some *ideas* on how
to handle his problem, not do it for him. I never stated that it was
production-quality code. It was a hack to deal with an improperly formatted
table of data.

It took all of 5-10 minutes to cut and paste, was very ugly, and there were
a lot of things wrong with the code but it worked and it showed the results
that *could* be accomplished.

Feel free to optimize, test, debug, and repost, as you (apparently) have
more free time on your hands than I.

Thanks for the critique,

Rich

Jan 14 '06 #9
Rich wrote:

"Pedro Graca" <he****@dodgeit .com> wrote in message
news:sl******** ***********@ID-203069.user.ind ividual.net...

<snip>
If your table has 1000 names you'd do 1001 queries (one for the
DISTINCT names and 1000 for the classes)


You're right. If there were 1000 names you should loop through the results
of 1 query. But there were only 5.


Usually people post a stripped-down example of their problem.
Just because the example posted by the OP contained 5 rows, that's no
reason to assume the real problem happens only with a small amount of
data.
Yes, it gets the desired results, but at a *very large* cost!

<snip>


I took a few minutes out of my busy day to give the OP some *ideas* on how
to handle his problem, not do it for him. I never stated that it was
production-quality code. It was a hack to deal with an improperly formatted
table of data.

It took all of 5-10 minutes to cut and paste, was very ugly, and there were
a lot of things wrong with the code but it worked and it showed the results
that *could* be accomplished.

Feel free to optimize, test, debug, and repost, as you (apparently) have
more free time on your hands than I.

Thanks for the critique,


Don't take my criticism personally, I never intended it that way.
I can't speak for anyone else on these groups, but I'm sure all of us
appreciate your posts.
--
Mail to my "From:" address is readable by all at http://www.dodgeit.com/
== ** ## !! ------------------------------------------------ !! ## ** ==
TEXT-ONLY mail to the whole "Reply-To:" address ("My Name" <my@address>)
may bypass my spam filter. If it does, I may reply from another address!
Jan 15 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
5398
by: joemyre | last post by:
Hi everyone, What I'm trying to do is take php variables i got from user input, and pass them as the MySQL query terms. $query = "select * from ident where ".$searchtype1."=".$searchterm1.""; ERROR: Invalid query: You have an error in your SQL syntax near '=' at line 1
16
2737
by: cover | last post by:
I have a form with drop down menus to query for name, month, and year to capture activity accordingly by an individual for a given month and given year. But I'd like to also be able to query ALL individiduals for a given month and year OR an individual for the whole year for example. My question, is there any way to have blank (not filled in) fields of a query input ignored when left blank? I'm currently doing very successfully what I...
3
1955
by: Nick Truscott | last post by:
<? // scoreinput.php - input a match score when match selected from list ?> <html> <head> <basefont face="Verdana"> </head> <body>
0
1693
by: ChangAya | last post by:
I use binary log on mysql system. Yesterday i found some hacking attempt on my machine. ( I found some unknown queries on binary log) But i don't get any information about hacking query connection on binary log file.. ( username, host.. i don't know anything ) only thing that i know is "thread_id".
8
3271
by: Együd Csaba | last post by:
Hi All, how can I improve the query performance in the following situation: I have a big (4.5+ million rows) table. One query takes approx. 9 sec to finish resulting ~10000 rows. But if I run simultaneously 4 similar queries it takes nearly 5 minutes instead of 4 times 9 seconds or something near of that. here is a sample query: select mertido, fomeazon, ertektipus, mertertek from t_me30 where fomeazon in (select distinct fomeazon...
4
3580
by: Steve | last post by:
I have a products table where the PK is ProductID. Also have the standard Orders table and OrderDetails table. I created a query that joins the Orders table and OrderDetails table. The query includes the OrderDate field from the Orders table and the ProductID field from the OrderDetails table. I added a criteria to the OrderDate field to limit the orders to the past year. Then I converted the query to a totals query to get the total sold of...
1
3092
by: Nicolae Fieraru | last post by:
Hi All, I want to find if there is a different way than the way I am working now. Lets say I have a table, tblCustomers containing address details. I want a report with all the customers from a specific state. In order to generate that, I create a form, I put a combobox with the states and a Command Button which opens a report. The report is based on a query, qryCustomersByState which has a parameter (State) taken from the Form.
5
10600
by: Ryan Hubbard | last post by:
Is it possible to get the recordset from an open query window? So you run the query. The window is open. Can vba retrieve this data?
21
6984
by: CSN | last post by:
I have a pretty simple select query that joins a table (p) with 125K rows with another table (pc) with almost one million rows: select p.* from product_categories pc inner join products p on pc.product_id = p.id where pc.category_id = $category_id order by p.title
4
8012
by: Gary | last post by:
Hi, I get this error " " when my web page run, what does it mean? Hope someone can help!!! Gary
0
9650
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9497
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10164
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10110
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7515
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6748
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5398
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3670
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.