Related
I am a novice to MySQL
I have a database where I want to populate sets of records from 'sales' table where condition is sales is not delivered by comparing with 'deliveries' table of 'deliveries.reference_no'.
Both Tables has reference_no in common which is the invoice ref number.
I tried few SQL and got all common filed as it is and tried this one below but its displaying #1052 - Column 'date' in field list is ambiguous.
SELECT sales.id AS sid, date, reference_no, biller_name, customer_name, total_tax, total_tax2, total, internal_note FROM sales LEFT JOIN deliveries ON (sales.reference_no = deliveries.reference_no)
For more information below is my two table schema
Sales
CREATE TABLE IF NOT EXISTS `sales` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`reference_no` varchar(55) NOT NULL,
`warehouse_id` int(11) DEFAULT NULL,
`biller_id` int(11) NOT NULL,
`biller_name` varchar(55) NOT NULL,
`customer_id` int(11) NOT NULL,
`customer_name` varchar(55) NOT NULL,
`date` date NOT NULL,
`note` varchar(1000) DEFAULT NULL,
`internal_note` varchar(1000) DEFAULT NULL,
`inv_total` decimal(25,2) NOT NULL,
`total_tax` decimal(25,2) DEFAULT NULL,
`total` decimal(25,2) NOT NULL,
`invoice_type` int(11) DEFAULT NULL,
`in_type` varchar(55) DEFAULT NULL,
`total_tax2` decimal(25,2) DEFAULT NULL,
`tax_rate2_id` int(11) DEFAULT NULL,
`inv_discount` decimal(25,2) DEFAULT NULL,
`discount_id` int(11) DEFAULT NULL,
`user` varchar(255) DEFAULT NULL,
`updated_by` varchar(255) DEFAULT NULL,
`paid_by` varchar(55) DEFAULT 'cash',
`count` int(11) DEFAULT NULL,
`shipping` decimal(25,2) DEFAULT '0.00',
`pos` tinyint(4) NOT NULL DEFAULT '0',
`paid` decimal(25,2) DEFAULT NULL,
`cc_no` varchar(20) DEFAULT NULL,
`cc_holder` varchar(100) DEFAULT NULL,
`cheque_no` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
Deliveries
CREATE TABLE IF NOT EXISTS `deliveries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
`time` varchar(10) NOT NULL,
`reference_no` varchar(55) NOT NULL,
`customer` varchar(55) NOT NULL,
`address` varchar(1000) NOT NULL,
`note` varchar(1000) DEFAULT NULL,
`user` varchar(255) DEFAULT NULL,
`updated_by` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
Currently I have a CI program and I am doing like this no Luck what I want to populate
CI PHP
function getdatatableajax()
{
if($this->input->get('search_term')) { $search_term = $this->input->get('search_term'); } else { $search_term = false;}
$this->load->library('datatables');
$this->datatables
->select("sales.id as sid, date, reference_no, biller_name, customer_name, total_tax, total_tax2, total, internal_note")
->from('sales');
$this->datatables->add_column("Actions",
"<center><a href='#' title='$2' class='tip' data-html='true'><i class='icon-folder-close'></i></a> <a href='#' onClick=\"MyWindow=window.open('index.php?module=sales&view=view_invoice&id=$1', 'MyWindow','toolbar=0,location=0,directories=0,status=0,menubar=yes,scrollbars=yes,resizable=yes,width=1000,height=600'); return false;\" title='".$this->lang->line("view_invoice")."' class='tip'><i class='icon-fullscreen'></i></a>
<a href='index.php?module=sales&view=add_delivery&id=$1' title='".$this->lang->line("add_delivery_order")."' class='tip'><i class='icon-road'></i></a>
<a href='index.php?module=sales&view=pdf&id=$1' title='".$this->lang->line("download_pdf")."' class='tip'><i class='icon-file'></i></a>
<a href='index.php?module=sales&view=email_invoice&id=$1' title='".$this->lang->line("email_invoice")."' class='tip'><i class='icon-envelope'></i></a>
</center>", "sid, internal_note")
->unset_column('sid')
->unset_column('internal_note');
echo $this->datatables->generate();
}
Wow, no one answered this yet? Strange.
Your error is because the date field is in both tables. You have to specify which table you want to select date from. So you must write either sales.date or deliveries.date. This goes with the rest of them, once you fix sales.date, your next field reference_no will generate the same error. If you want data from BOTH tables you'll need to assign aliases to them as you did with the first column.
sales.id AS sid, sales.date AS sales_date, deliveries.date AS deliveries_date etc...
i have a problem in my examination system. In the admin panel, in the results page displays the correct score but the firstname and the last name not. I dont know what to do.
Here is the code:
$result1=executeQuery("select s.nume_student,s.prenume_student,s.stdname,s.stdid, IFNULL((select sum(q.marks) from studentquestion as sq,question as q where q.qnid=sq.qnid and sq.testid=".$_REQUEST['testid']." and sq.stdid=st.stdid and sq.stdanswer=q.correctanswer),0) as om from studenttest as st, student as s where s.stdid=st.stdid and st.testid=".$_REQUEST['testid'].";" );
$result3=executeQuery("SELECT sq.stdid, sq.testid, COUNT(*) AS correctAnswers, SUM(q.marks) AS studentScore,(SELECT SUM(marks) FROM question WHERE testid=".$_REQUEST['testid'].") AS totalScore FROM question q, studentquestion sq WHERE sq.testid=".$_REQUEST['testid']." AND q.testid = sq.testid AND q.qnid = sq.qnid AND sq.answered = 'answered' AND q.correctanswer = sq.stdanswer GROUP BY sq.stdid");
without $result1 doesen't display anything
And here are the tables from database:
question table:
CREATE TABLE IF NOT EXISTS `question` (
`testid` bigint(20) NOT NULL DEFAULT '0',
`qnid` int(11) NOT NULL DEFAULT '0',
`question` varchar(500) DEFAULT NULL,
`optiona` varchar(100) DEFAULT NULL,
`optionb` varchar(100) DEFAULT NULL,
`optionc` varchar(100) DEFAULT NULL,
`optiond` varchar(100) DEFAULT NULL,
`correctanswer` enum('optiona','optionb','optionc','optiond') DEFAULT NULL,
`marks` float(3,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
studentquestion table:
CREATE TABLE IF NOT EXISTS `studentquestion` (
`stdid` bigint(20) NOT NULL DEFAULT '0',
`testid` bigint(20) NOT NULL DEFAULT '0',
`qnid` int(11) NOT NULL DEFAULT '0',
`answered` enum('answered','unanswered','review') DEFAULT NULL,
`stdanswer` enum('optiona','optionb','optionc','optiond') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
student table:
CREATE TABLE IF NOT EXISTS `student` (
`stdid` bigint(20) NOT NULL,
`stdname` varchar(40) DEFAULT NULL,
`stdpassword` varchar(40) DEFAULT NULL,
`emailid` varchar(40) DEFAULT NULL,
`contactno` varchar(20) DEFAULT NULL,
`fname` varchar(40) DEFAULT NULL,
`lname` varchar(40) DEFAULT NULL,
`pincode` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
student test table:
CREATE TABLE IF NOT EXISTS `studenttest` (
`stdid` bigint(20) NOT NULL DEFAULT '0',
`testid` bigint(20) NOT NULL DEFAULT '0',
`starttime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`endtime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`correctlyanswered` int(11) DEFAULT NULL,
`status` enum('over','inprogress') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and test table:
CREATE TABLE IF NOT EXISTS `test` (
`testid` bigint(20) NOT NULL,
`testname` varchar(30) NOT NULL,
`testdesc` varchar(100) DEFAULT NULL,
`testdate` date DEFAULT NULL,
`testtime` time DEFAULT NULL,
`subid` int(11) DEFAULT NULL,
`testfrom` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`testto` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`duration` int(11) DEFAULT NULL,
`totalquestions` int(11) DEFAULT NULL,
`attemptedstudents` bigint(20) DEFAULT NULL,
`testcode` varchar(40) NOT NULL,
`tcid` bigint(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I resolved the same problem of here:
How to get sql WHERE statement auto update from localhost link
but i'm stucked here with fname and last name.
If your second query returns the correct student ids, you can just change it to add student names:
SELECT s.lastname, s.firstname, e.*
from
students s join (
... your second query ... ) e
on s.stdid=e.stdid
you can change your join type depends on what you want.
Thanks, but i resolved it like this:
SELECT ***s.fname, s.lname***, sq.stdid, sq.testid, COUNT(*) AS correctAnswers,
SUM(q.marks) AS studentScore,(SELECT SUM(marks) FROM question
WHERE testid=1) AS totalScore
FROM question q, studentquestion sq, ***student s***
WHERE sq.testid=1 AND q.testid = sq.testid
AND q.qnid = sq.qnid AND sq.answered = 'answered' ***and sq.stdid=s.stdid***
AND q.correctanswer = sq.stdanswer GROUP BY sq.stdid
I have a table called "tables_data_info" where is stored some of the data relative to different tables. Data like "created time", "editing time", "editing user", "create by user id" etc. I'm using this table because there was a dynamic php script that generate it automatically.
But, when i have a huge number of record ( 15k in this case ) the query getting very very very slow, and take "minutes" to do his job! But i'm not selecting all 15k records, i'm limiting to select 10 records at all!
A simple query:
SELECT pd.id, pd.title, pd.sell_price, pd.available_qt, tdi.createtime, tdi.lastupdatetime, tdi.create_member_id, tdi.create_group_id, tdi.last_update_member_id, tdi.last_update_group_id FROM zd_products AS pd LEFT JOIN zd_tables_data_info AS tdi ON ( tdi.targetid = pd.id and tdi.table_name = 'products' ) ORDER by pd.title ASC LIMIT 0, 10
How can i run this query differently but more efficiently ?
Here the table structure:
zd_products
CREATE TABLE `zd_products` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(256) NOT NULL DEFAULT '',
`internalcode` varchar(256) DEFAULT NULL,
`ean13_jan_code` varchar(256) DEFAULT NULL,
`upc_code` varchar(11) DEFAULT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0',
`status` varchar(12) NOT NULL DEFAULT 'new',
`product_tags` longtext,
`buy_price` double NOT NULL DEFAULT '0',
`sell_price` double NOT NULL DEFAULT '0',
`fiscal_tax_id` int(11) NOT NULL DEFAULT '0',
`box_width` double NOT NULL DEFAULT '0',
`box_height` double NOT NULL DEFAULT '0',
`box_depth` double NOT NULL DEFAULT '0',
`box_weight` double NOT NULL DEFAULT '0',
`shipment_extra_price` double NOT NULL DEFAULT '0',
`available_qt` int(11) NOT NULL DEFAULT '0',
`allow_purchase_out_stock` tinyint(1) NOT NULL DEFAULT '0',
`meta_title` varchar(256) DEFAULT NULL,
`meta_description` varchar(256) DEFAULT NULL,
`meta_keywords` longtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15730 DEFAULT CHARSET=utf8;
zd_tables_data_info
CREATE TABLE `zd_tables_data_info` (
`table_name` varchar(256) NOT NULL DEFAULT '',
`targetid` int(11) DEFAULT NULL,
`create_member_id` int(11) unsigned DEFAULT NULL,
`create_group_id` int(11) unsigned DEFAULT NULL,
`last_update_member_id` int(11) unsigned DEFAULT NULL,
`last_update_group_id` int(11) unsigned DEFAULT NULL,
`createtime` int(11) unsigned DEFAULT NULL,
`lastupdatetime` int(11) unsigned DEFAULT NULL,
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `INDEX` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19692 DEFAULT CHARSET=utf8;
Your data is not particularly big. Here is the query:
SELECT pd.id, pd.title, pd.sell_price, pd.available_qt,
tdi.createtime, tdi.lastupdatetime, tdi.create_member_id, tdi.create_group_id,
tdi.last_update_member_id, tdi.last_update_group_id
FROM zd_products pd LEFT JOIN
zd_tables_data_info tdi
ON tdi.targetid = pd.id and tdi.table_name = 'products'
ORDER by pd.title ASC
LIMIT 0, 10;
You can improve performance of this query with indexes. The two that come to mind are zd_products(title, id) and zd_tables_data_info(targetid, table_name). Try these and see if they help. You can create these indexes either in the create table statement (or alter table) or by using:
create index zd_products_title_id on zd_products(title, id);
create index zd_tables_data_info_targetid_table_name on zd_tables_data_info(targetid, table_name);
If not, put explain in front of your query and then edit your question with the resulting plan.
Abstract:
Every client is given a specific xml ad feed (publisher_feed table). Everytime there is a query or a click on that feed, it gets recorded (publisher_stats_raw table) (Each query/click will have multiple rows depending on the subid passed by the client (We can sum the clicks together)). The next day, we pull stats from an API to grab the previous days revenue numbers (rev_stats table) (Each revenue stat might have multiple rows depending on the country of the click (We can sum the revenue together)). Been having a hard time trying to link together these three tables to find the average RPC for each client for the previous day.
Table Structure:
CREATE TABLE `publisher_feed` (
`publisher_feed_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`alias` varchar(45) DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
`remote_feed_id` int(10) unsigned DEFAULT NULL,
`subid` varchar(255) DEFAULT '',
`requirement` enum('tq','tier2','ron','cpv','tos1','tos2','tos3','pv1','pv2','pv3','ar','ht') DEFAULT NULL,
`status` enum('enabled','disabled') DEFAULT 'enabled',
`tq` decimal(4,2) DEFAULT '0.00',
`clicklimit` int(11) DEFAULT '0',
`prev_rpc` decimal(20,10) DEFAULT '0.0000000000',
PRIMARY KEY (`publisher_feed_id`),
UNIQUE KEY `alias_UNIQUE` (`alias`),
KEY `publisher_feed_idx` (`remote_feed_id`),
KEY `publisher_feed_user` (`user_id`),
CONSTRAINT `publisher_feed_feed` FOREIGN KEY (`remote_feed_id`) REFERENCES `remote_feed` (`remote_feed_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `publisher_feed_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=124 DEFAULT CHARSET=latin1$$
CREATE TABLE `publisher_stats_raw` (
`publisher_stats_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`unique_data` varchar(350) NOT NULL,
`publisher_feed_id` int(10) unsigned DEFAULT NULL,
`date` date DEFAULT NULL,
`subid` varchar(255) DEFAULT NULL,
`queries` int(10) unsigned DEFAULT '0',
`impressions` int(10) unsigned DEFAULT '0',
`clicks` int(10) unsigned DEFAULT '0',
`filtered` int(10) unsigned DEFAULT '0',
`revenue` decimal(20,10) unsigned DEFAULT '0.0000000000',
PRIMARY KEY (`publisher_stats_id`),
UNIQUE KEY `unique_data_UNIQUE` (`unique_data`),
KEY `publisher_stats_raw_remote_feed_idx` (`publisher_feed_id`)
) ENGINE=InnoDB AUTO_INCREMENT=472 DEFAULT CHARSET=latin1$$
CREATE TABLE `rev_stats` (
`rev_stats_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date` date DEFAULT NULL,
`remote_feed_id` int(10) unsigned DEFAULT NULL,
`typetag` varchar(255) DEFAULT NULL,
`subid` varchar(255) DEFAULT NULL,
`country` varchar(2) DEFAULT NULL,
`revenue` decimal(20,10) DEFAULT NULL,
`tq` decimal(4,2) DEFAULT NULL,
`finalized` int(11) DEFAULT '0',
PRIMARY KEY (`rev_stats_id`),
KEY `rev_stats_remote_feed_idx` (`remote_feed_id`),
CONSTRAINT `rev_stats_remote_feed` FOREIGN KEY (`remote_feed_id`) REFERENCES `remote_feed` (`remote_feed_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=latin1$$
Context:
Each remote_feed has a specific subid/typetag given to it. So we need to match up the both the remote_feed_id and the subid columsn from the publisher_feed table to the remote_feed_id and typetag columns in the revenue stats table.
My current, non working, implementation:
SELECT
pf.publisher_feed_id, psr.date, sum(clicks), sum(rs.revenue)
FROM
xml_network.publisher_feed pf
JOIN
xml_network.publisher_stats_raw psr
ON
psr.publisher_feed_id = pf.publisher_feed_id
JOIN
xml_network.rev_stats rs
ON
rs.remote_feed_id = pf.remote_feed_id
WHERE
pf.requirement = 'tq'
AND
pf.subid = rs.typetag
AND
psr.date <> date(curdate())
GROUP BY
psr.date
ORDER BY
psr.date DESC
LIMIT 1;
The above keeps pulling the wrong data out of the rev_stats table (pulls the sum of the correct stats, but repeats it over because of a join). Any help with how I would be able to properly pull the correct data would be greatly helpful ( I could use multiple queries and PHP to get the correct results, but what's the fun in that!)
Figured out a way to get this accomplished. Its def not a fast method by any means, needing 4 selects to get it done, but it works flawlessly =)
SELECT
pf.publisher_feed_id,
round(
(
SELECT
SUM(rs.revenue)
FROM
xml_network.rev_stats rs
WHERE
rs.remote_feed_id = pf.remote_feed_id
AND
rs.typetag = pf.subid
AND
rs.date = subdate(current_date, 1)
),10)as revenue,
(
SELECT
MAX(rs.tq)
FROM
xml_network.rev_stats rs
WHERE
rs.remote_feed_id = pf.remote_feed_id
AND
rs.typetag = pf.subid
AND
rs.date = subdate(current_date, 1)
) as tq,
(
SELECT
SUM(psr.clicks)-SUM(psr.filtered)
FROM
xml_network.publisher_stats_raw psr
WHERE
psr.publisher_feed_id = pf.publisher_feed_id
AND
psr.date = subdate(current_date, 1)
) as clicks
FROM
xml_network.publisher_feed pf
WHERE
pf.requirement = 'tq';
I use the following prepared statement:
SELECT *
FROM
c_members,c_users,c_positions,c_done_meetings
WHERE
c_positions.POS_ID=c_users.POS_ID
AND c_members.CLUB_ID = ?
AND USER_POINTS >= ?
AND USER_POINTS <= ?
AND c_users.POS_ID LIKE ?
AND MEM_ACADEMY LIKE ?
AND MEM_SEX LIKE ?
AND MEM_GRADELVL LIKE ?
AND MEM_GPA >= ?
AND MEM_GPA <= ?
AND MEM_ARCHIVE = 0
GROUP BY
c_members.MEM_ID, c_members.CLUB_ID
HAVING
SUM(c_done_meetings.MEDONE_ATTEND = 'u') >= 1
ORDER BY
USER_POINTS DESC
However this query takes 21.971405982971 seconds to load 111 records. When I remove "Having SUM(...)" clause, the performance is 100% better. Is there a way I could optimize it better?
Edit: (Table structures)
CREATE TABLE IF NOT EXISTS `c_done_meetings` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`MEETING_ID` int(11) NOT NULL,
`MEDONE_ATTEND` varchar(1) NOT NULL COMMENT 'E=excused, U=unexcused, P=present',
UNIQUE KEY `unique` (`MEM_ID`,`CLUB_ID`,`MEETING_ID`),
KEY `MEETING_ID` (`MEETING_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `c_members` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`MEM_FIRST` varchar(50) NOT NULL,
`MEM_MIDDLE` varchar(50) DEFAULT NULL,
`MEM_LAST` varchar(50) NOT NULL,
`MEM_SEX` tinyint(1) NOT NULL COMMENT '0-Male 1-Female',
`MEM_EMAIL` varchar(100) DEFAULT NULL,
`MEM_GRADELVL` int(11) NOT NULL,
`MEM_ACADEMY` varchar(50) DEFAULT '',
`MEM_GPA` double DEFAULT '0',
`MEM_ADDRESS` varchar(500) DEFAULT NULL,
`MEM_CITY` varchar(100) DEFAULT NULL,
`MEM_STATE` varchar(100) DEFAULT NULL,
`MEM_ZIP` int(11) DEFAULT NULL,
`MEM_TELEPHONE` varchar(25) DEFAULT NULL,
`MEM_AP` tinyint(1) NOT NULL,
`MEM_HONORS` tinyint(1) NOT NULL,
`MEM_ESOL` tinyint(1) NOT NULL,
`MEM_HISP` tinyint(1) NOT NULL,
`MEM_WHITE` tinyint(1) NOT NULL,
`MEM_MULTI` tinyint(1) NOT NULL,
`MEM_NATIVE` tinyint(1) NOT NULL,
`MEM_BLACK` tinyint(1) NOT NULL,
`MEM_ASIAN` tinyint(1) NOT NULL,
`MEM_EXTRA` varchar(10000) DEFAULT NULL,
`MEM_ARCHIVE` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `MEM_ID` (`MEM_ID`,`CLUB_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `c_positions` (
`POS_ID` int(11) NOT NULL AUTO_INCREMENT,
`CLUB_ID` int(11) NOT NULL,
`POS_NAME` varchar(20) NOT NULL,
`POS_DESC` varchar(500) NOT NULL,
`POS_ADMIN` tinyint(1) NOT NULL,
`POS_ATN_VIEW` tinyint(1) NOT NULL,
`POS_ATN_CHKIN` tinyint(1) NOT NULL,
`POS_ATN_FINALIZE` tinyint(1) NOT NULL,
`POS_MEM_VIEW` tinyint(1) NOT NULL,
`POS_MEM_ADD` tinyint(1) NOT NULL,
`POS_MEM_EDIT` tinyint(1) NOT NULL,
`POS_POS_VIEW` tinyint(1) NOT NULL,
`POS_POS_ADD` tinyint(1) NOT NULL,
`POS_POS_EDIT` tinyint(1) NOT NULL,
`POS_MEET_VIEW` tinyint(1) NOT NULL,
`POS_MEET_ADD` tinyint(1) NOT NULL,
`POS_MEET_EDIT` tinyint(1) NOT NULL,
`POS_EVENT_VIEW` tinyint(1) NOT NULL,
`POS_EVENT_ADD` tinyint(1) NOT NULL,
`POS_EVENT_EDIT` tinyint(1) NOT NULL,
`POS_EVENT_UPDATE` tinyint(1) NOT NULL,
`POS_REPORT_VIEW` tinyint(1) NOT NULL,
`POS_ARCHIVE_VIEW` tinyint(1) NOT NULL,
`POS_ANNOUNCEMENTS` tinyint(1) NOT NULL,
`POS_WEB_CUSTOM` tinyint(1) NOT NULL,
PRIMARY KEY (`POS_ID`),
UNIQUE KEY `UNIQUE_NAME` (`CLUB_ID`,`POS_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
CREATE TABLE IF NOT EXISTS `c_users` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`USER_PIN` int(11) NOT NULL,
`USER_POINTS` double NOT NULL,
`POS_ID` int(11) NOT NULL,
`USER_ARCHIVE` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `MEM_ID` (`MEM_ID`,`CLUB_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Edit 2:
Yes all ids are indexed, the SUM(...) >= # calculates the number of missed meetings. # is a parameter set by the user (I just hard coded a 1 for testing)
You need to have indexes an all fields used in the WHERE clause, on all fields on which the tables are joined (you need to explicitly state your join conditions as right now, you are getting a Cartesian join), on all fields used for grouping and all fields used for sorting.
The last problem is the HAVING clause there. You are not going to be able to use an index at all for that since it is a calculated value. If this is a query you will use often in the system (i.e. not just for reporting), you might consider adding a field you can use as a flag for this filtering purpose. Whenever you set c_done_meetings.MEDONE_ATTEND = 'u' in any of your queries, you could also set this flag for the member or user or whatever this is associated with so that you have an easy field to filter on in a WHERE clause.
Outside of that, you might actually gain better performance by getting a reduced list of users or members with that value of u in a subselect and then join using that subselect as a table.
EDIT:
After seeing your actual table structure, I can clearly see where you need to add indexes. I am also wondering why you have tables c_users and c_members with the same exact primary key. Why would these not just be a single table?
Some things that pop out at me:
You use like quite a lot. Try to do something with your php code so that this isn't necessary. For example, mem_sex has a limited number of choices. Make the front end a radio button or dropdown so you send a value where you can use = instead of like.
Two, if you add a sum() to the select clause, and the appropriate group by clause, it should run faster. It's worth a shot.
You can denormalise you tables and add field to c_members that represent your
SUM(c_done_meetings.MEDONE_ATTEND = 'u') >= 1
But you need to update that field always, when updating c_done_meetings (can be done with trigger)
Also try to avoid LIKE conditions. Use = insead (it is possible at least for SEX)