Mysql database query - php

I want to fetch data from mysql in three 3 tables. I am using LEFT OUTER JOIN. This is my query:
SELECT cms_addresses.address1 as add1,
cms_addresses.email as ademail,
cms_addresses.city as adcity,
cms_addresses.clientid
cms_addresses.country as adcountry,
cms_addresses.province as adprovince,
cms_addresses.postal as adprovince,
cms_delivery_info.d_address1,
cms_delivery_info.d_city,
cms_delivery_info.d_country,
cms_delivery_info.d_province,
cms_delivery_info.d_postal,
cms_orders.id,
cms_orders.cdate,
cms_orders.message
FROM cms_addresses
LEFT OUTER JOIN cms_delivery_info
ON cms_addresses.clientid = cms_delivery_info.d_clientid
LEFT OUTER JOIN cms_orders = cms_addresses.clientid = cms_orders.clientid
WHERE cms_orders.id = 10
and cms_addresses.addresstypeid = 1
Problem is that this query is not running and gives me that error.
Not unique table/alias: 'cms_addresses'
Please help me out to resolve this. thanks

You had a syntactical error in the second left join, where there was '=' after the table name
TRy this::
SELECT
cms_addresses.address1 as add1,
cms_addresses.email as ademail,
cms_addresses.city as adcity,
cms_addresses.clientid,
cms_addresses.country as adcountry,
cms_addresses.province as adprovince,
cms_addresses.postal as adprovince,
cms_delivery_info.d_address1,
cms_delivery_info.d_city,
cms_delivery_info.d_country,
cms_delivery_info.d_province,
cms_delivery_info.d_postal,
cms_orders.id,
cms_orders.cdate,
cms_orders.message
FROM cms_addresses
LEFT OUTER JOIN cms_delivery_info ON cms_addresses.clientid = cms_delivery_info.d_clientid
LEFT OUTER JOIN cms_orders on cms_addresses.clientid = cms_orders.clientid
WHERE cms_orders.id = 10 and cms_addresses.addresstypeid = 1

put a comma between cms_addresses.clientid and cms_addresses.country AS adcountry and see if it works
SELECT cms_addresses.address1 AS add1,
cms_addresses.email AS ademail,
cms_addresses.city AS adcity,
cms_addresses.clientid, // add comma here
cms_addresses.country AS adcountry,
cms_addresses.province AS adprovince,
cms_addresses.postal AS adprovince,
cms_delivery_info.d_address1,
cms_delivery_info.d_city,
cms_delivery_info.d_country,
cms_delivery_info.d_province,
cms_delivery_info.d_postal,
cms_orders.id,
cms_orders.cdate,
cms_orders.message
FROM cms_addresses
LEFT JOIN cms_delivery_info
ON cms_addresses.clientid = cms_delivery_info.d_clientid
LEFT JOIN cms_orders
// use ON instead of = (equal sign) here
ON cms_addresses.clientid = cms_orders.clientid
WHERE cms_orders.id = 10 AND cms_addresses.addresstypeid = 1

In your SELECT you have at some point:
cms_addresses.clientid cms_addresses.country as adcountry,
which looks like you missed a , somewhere?
In your FROM you have:
LEFT OUTER JOIN cms_orders = cms_addresses.clientid = cms_orders.clientid
which again I'm guessing is a typo (first = should be a ON).
The message you are getting means you are reusing the table cms_addresses in your JOIN chain and you are not giving it an alias, which is mandatory for disambiguation, but in your case it's weird because you don't have cms_addresses more than once in the FROM clause.
I'd try rewriting the query giving aliases to all tables. Also enable full logging and check what really reaches Mysql.

Related

MySql query duplicating results (with certain parameters)

I have a fairly complex query (to me) that returns duplicate results ONLY when the parameter passed results in 'dest_xdock: ' . $row['dest_xdock'] as a certain value. Can anyone identify why this is happening in the Query? I don't have duplicates of this in the table that I can see. Here is the query:
select
`orig_lookup`.`zipcode` AS `orig_zipcode`,
`orig_lookup`.`state` AS `orig_state`,
`orig_lookup`.`svcnotes` AS `orig_svcnotes`,
`orig_lookup`.`svcterms` AS `orig_svcterms`,
`orig_lookup`.`daysout` AS `orig_daysout`,
`orig_lookup`.`daysin` AS `orig_daysin`,
`orig_lookup`.`pcity` AS `orig_city`,
`orig_lookup`.`scac` AS `orig_scac`,
`orig_lookup`.`xdock` AS `orig_xdock`,
`orig_lookup`.`scac2` AS `orig_scac2`,
`orig_lookup`.`xdock2` AS `orig_xdock2`,
`orig_lookup`.`scac3` AS `orig_scac3`,
`orig_lookup`.`xdock3` AS `orig_xdock3`,
`orig_ssas`.`ssa` AS `orig_ssa`,
`orig_hcas`.`hca` AS `orig_hca`,
`dest_lookup`.`zipcode` AS `dest_zipcode`,
`dest_lookup`.`state` AS `dest_state`,
`dest_lookup`.`svcnotes` AS `dest_svcnotes`,
`dest_lookup`.`svcterms` AS `dest_svcterms`,
`dest_lookup`.`daysout` AS `dest_daysout`,
`dest_lookup`.`daysin` AS `dest_daysin`,
`dest_lookup`.`pcity` AS `dest_city`,
`dest_lookup`.`scac` AS `dest_scac`,
`dest_lookup`.`xdock` AS `dest_xdock`,
`dest_lookup`.`scac2` AS `dest_scac2`,
`dest_lookup`.`xdock2` AS `dest_xdock2`,
`dest_lookup`.`scac3` AS `dest_scac3`,
`dest_lookup`.`xdock3` AS `dest_xdock3`,
`dest_ssas`.`ssa` AS `dest_ssa`,
`dest_hcas`.`hca` AS `dest_hca`,
`tbl_matx_20160321`.`trmnljoin` AS `TrmnlMatx`,
`tbl_matx_20160321`.`trmnlsvcdays` AS `TrmnlSvcDays`,
`tbl_matx_20160321`.`trmnltranspts` AS `TrmnlTransPts`,
IF(ISNULL(`orig_lookup`.`daysin`+ `dest_lookup`.`daysout`+ `tbl_matx_20160321`.`trmnlsvcdays`), 'No Service',(`orig_lookup`.`daysin`+ `dest_lookup`.`daysout`+ `tbl_matx_20160321`.`trmnlsvcdays`)) AS `TotalSvcDays`
FROM ((`tbl_uscomp_20160321` AS `orig_lookup` LEFT JOIN `tbl_hcas_20160321` AS `orig_hcas` ON `orig_lookup`.`zipcode` = `orig_hcas`.`zipcode` LEFT JOIN `tbl_ssas_20160321` AS `orig_ssas` ON `orig_lookup`.`zipcode` = `orig_ssas`.`zipcode`)
INNER JOIN (`tbl_uscomp_20160321` AS `dest_lookup` LEFT JOIN `tbl_hcas_20160321` AS `dest_hcas` ON `dest_lookup`.`zipcode` = `dest_hcas`.`zipcode` LEFT JOIN `tbl_ssas_20160321` AS `dest_ssas` ON `dest_lookup`.`zipcode` = `dest_ssas`.`zipcode`)
INNER JOIN `tbl_matx_20160321` ON (`orig_lookup`.`xdock` = `tbl_matx_20160321`.`otrmnl` AND `dest_lookup`.`xdock` = `tbl_matx_20160321`.`dtrmnl`))
WHERE `orig_lookup`.`zipcode` = '$ziporig' AND `dest_lookup`.`zipcode` = '$zipdest'",

My MySQLi query gives error but i can't find out thats wrong with it

I'm working with a mysql query to select data from multiple tables using LEFT OUTER JOIN. Now i get the following error when i exequte the query:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'wg.werkbon_global_id = wk.werkbon_klant_globalid LEFT OUTER
JOIN users AS u' at line 16
Only the problem is that i can't find out what's wrong with my query.
PHP Query:
$query = '
SELECT
wg.werkbon_global_id AS id,
wg.werkbon_global_status AS status,
wg.werkbon_global_date_lastedit AS date,
usr.user_firstname AS monteur_vn,
usr.user_insertion AS monteur_tv,
usr.user_lastname AS monteur_an,
wg.werkbon_global_type AS type,
wg.werkbon_global_layout AS layout,
wg.werkbon_global_werkzaamheden AS werkzaamheden,
wg.werkbon_global_opmerkingen AS opmerkingen,
wk.werkbon_klant_nummer AS klantnr
FROM
werkbon_klant AS wk
LEFT OUTER JOIN werkbon_global AS wg
wg.werkbon_global_id = wk.werkbon_klant_globalid
LEFT OUTER JOIN users AS usr
usr.user_id = wg.werkbon_global_monteur_finish
WHERE
wk.werkbon_klant_nummer = '.$db->Quote($klantid).'
ORDER BY id ASC;
$result = $db->loadAssoc($query);
I think my problem has something todo with left outer join but what?
You are missing the ON operator in your joins!
The correct syntax for a join is:
SELECT * FROM x LEFT JOIN y ON condition WHERE...
$query = "
SELECT
wg.werkbon_global_id AS id,
wg.werkbon_global_status AS status,
wg.werkbon_global_date_lastedit AS date,
usr.user_firstname AS monteur_vn,
usr.user_insertion AS monteur_tv,
usr.user_lastname AS monteur_an,
wg.werkbon_global_type AS type,
wg.werkbon_global_layout AS layout,
wg.werkbon_global_werkzaamheden AS werkzaamheden,
wg.werkbon_global_opmerkingen AS opmerkingen,
wk.werkbon_klant_nummer AS klantnr
FROM
werkbon_klant AS wk
LEFT OUTER JOIN werkbon_global AS wg
wg.werkbon_global_id = wk.werkbon_klant_globalid
LEFT OUTER JOIN users AS usr
usr.user_id = wg.werkbon_global_monteur_finish
WHERE
wk.werkbon_klant_nummer = '.$db->Quote($klantid).'
ORDER BY id ASC";
$result = $db->loadAssoc($query);
Make sure there isn't missing quote
Problem soved thanks to arkascha
The fixed query is now:
$query = '
SELECT
wg.werkbon_global_id AS id,
wg.werkbon_global_status AS status,
wg.werkbon_global_date_lastedit AS date,
usr.user_firstname AS monteur_vn,
usr.user_insertion AS monteur_tv,
usr.user_lastname AS monteur_an,
wg.werkbon_global_type AS type,
wg.werkbon_global_layout AS layout,
wg.werkbon_global_werkzaamheden AS werkzaamheden,
wg.werkbon_global_opmerkingen AS opmerkingen,
wk.werkbon_klant_nummer AS klantnr
FROM
werkbon_klant AS wk
LEFT OUTER JOIN werkbon_global AS wg ON
wg.werkbon_global_id = wk.werkbon_klant_globalid
LEFT OUTER JOIN users AS usr ON
usr.user_id = wg.werkbon_global_monteur_finish
WHERE
wk.werkbon_klant_nummer = '.$db->Quote($klantid).'
ORDER BY id ASC';
$result = $db->loadAssoc($query);
#fred i don't need to add quotes by column names. You only need to add quotes by string/blob values.
#johny my $db->Quote() function will add qoutes automaticly. I don't need to add them and put everything in quote's.
Thanks all for help.

Return all rows from table one even if table two is empty or partial results found

I am trying to return all the results from table one, AKA ship_skill_tree, while matching up the rows found in table two, AKA character_sheet_skills, even if the rows do not exist in table two.
SELECT c.`level` , t.`skillLevel` AS levelNeeded, i.`typeName`
FROM `ship_skill_tree` t
LEFT JOIN `character_sheet_skills` c ON t.`skillTypeID` = c.`typeID`
LEFT JOIN `invTypes` i ON i.`typeID` = t.`skillTypeID`
WHERE t.`shipTypeID` = 11176 AND c.`character_id` = 1;
Table One Data:
|shipTypeID|shipGroupID|skillTypeID|skillLevel
______________________________________________
|11011|26|3332|1
|11129|31|3327|1
|11132|31|3327|1
|11134|31|3327|1
|11172|830|3328|5
|11172|830|12093|1
|11174|893|3328|5
|11174|893|28615|1
|11176|831|3330|5
|11176|831|12092|1
Table Two Data:
|character_id|typeID|skillpoints|level|published
______________________________________________
|1|3300|1415|2|1
|1|3301|8000|3|1
|1|3327|256000|5|1
|1|3330|2829|2|1
|1|3340|181020|4|1
|1|3341|1024000|5|1
|1|3342|32000|3|1
|1|3343|32202|3|1
|1|3380|256000|5|1
|1|3385|256000|5|1
|1|3386|256000|5|1
|1|3392|256000|5|1
|1|3394|90514|4|1
|1|3402|256000|5|1
|1|3410|768000|5|1
|1|3411|135765|4|1
|1|3412|750|1|1
|1|3413|256000|5|1
|1|3416|45255|4|1
|1|3417|0|0|1
|1|3418|0|0|1
|1|3419|135765|4|1
|1|3420|181020|4|1
|1|3423|0|0|1
|1|3425|90510|4|1
|1|3426|45255|4|1
|1|3428|500|1|1
|1|3429|8000|3|1
|1|3436|45255|4|1
|1|3437|45255|4|1
|1|3438|500|1|1
|1|3449|256000|5|1
|1|3453|0|0|1
|1|3455|256000|5|1
|1|3456|226275|4|1
|1|11579|271530|4|1
|1|12186|0|0|1
|1|12187|0|0|1
|1|12188|0|0|1
|1|12190|22547|3|1
|1|12191|45255|4|1
|1|12192|45255|4|1
|1|12193|45255|4|1
|1|12195|45255|4|1
|1|16281|256000|5|1
|1|17940|1024000|5|1
|1|20342|1280000|5|1
|1|22551|40000|3|1
|1|22578|181020|4|1
|1|25739|0|0|1
|1|26252|16000|3|1
|1|26253|750|1|1
|1|26261|750|1|1
|1|32918|16000|3|1
invTypes table:
|typeID|typeName
________________
|3327|Spaceship Command
|3328|Gallente Frigate
|3330|Caldari Frigate
|3332|Gallente Cruiser
|12092|Interceptors
|12093|Covert Ops
|28615|Electronic Attack Ships
In the above query shipTypeID will always, or should always, be valid and match a record in table one, however, in table two, the rows that match may not exist. What I need is to output as follows:
|level|levelNeeded|typeName
___________________________
|2|5|Caldari Frigate
|NULL|1|Interceptors
Currently this is what is returned:
|level|levelNeeded|typeName
___________________________
|2|5|Caldari Frigate
EDIT: Solution!
SELECT c.`level` , t.`skillLevel` AS levelNeeded, i.`typeName`
FROM `ship_skill_tree` t
LEFT JOIN `character_sheet_skills` c ON t.`skillTypeID` = c.`typeID` AND c.`character_id` = 1
INNER JOIN `invTypes` i ON i.`typeID` = t.`skillTypeID`
WHERE t.`shipTypeID` = 11176
You need to put any restrictions on the table being joined in the ON clause. If you put them in the WHERE clause it doesn't work, because the rows that don't have any matches will produce NULL for those columns, and the WHERE clause will filter them out.
SELECT c.`level` , t.`skillLevel` AS levelNeeded, i.`typeName`
FROM `ship_skill_tree` t
LEFT JOIN `character_sheet_skills` c ON t.`skillTypeID` = c.`typeID` AND c.`character_id` = 1
LEFT JOIN `invTypes` i ON i.`typeID` = t.`skillTypeID`
WHERE t.`shipTypeID` = 11176
DEMO
You need to use a right join or an outer join rather than a left join. Have a look through the Visual Representation of SQL Joins for a good overview

mysql trasnposing rows to columns

I need to output the following query as csv.
I can easily write php logic to transpose the rows to columns from my group_concat column
However I am keen to keep as much of the data part in the database and minimize the manipulations on the php side.
I am experimenting with the two columns below the group_concat in the query.
The problem is the abundance value also returns for life_stage column. If there is no way around this other than manipulating the group_concat key values then that's fine, I just wanted to double check. Thanks in advance
SELECT
`tr`.`tr_id_pk` as 'RecordKey',
`t`.`tax_name` as `TaxonName`,
`tr`.`tr_date` as 'Date',
`s`.`si_name` as 'SiteName',
`tr`.`tr_grid_reference` as 'GridReference',
`tr`.`tr_is_site_grid` as 'IsSiteGrid',
`r`.`rec_name` as 'Recorder',
`r`.`rec_email` as 'RecorderEmail',
`tr`.`tr_comment` as 'RecordComment',
`tr`.`tr_last_update` as 'LastUpdated',
`tr`.`tr_form_key` as 'FormKey',
`c`.`co_name` as 'County',
`vc`.`vc_name` as 'ViceCounty',
`h`.`hab_name` as 'Habitat',
GROUP_CONCAT(DISTINCT CONCAT_WS('=', `ra`.`ra_name`, `rad`.`rad_value`)) as 'RecordAttributeKeyValuePairs',
`rad`.`rad_value` AS `abundance`,
`rad`.`rad_value` AS `life_stage`
FROM
`taxon_record`as `tr`
INNER JOIN
`taxon`as `t` ON `tr`.`tax_id_fk` = `t`.`tax_id_pk`
INNER JOIN
`recorder`as `r` ON `tr`.`rec_id_fk` = `r`.`rec_id_pk`
INNER JOIN
`site`as `s` ON `tr`.`si_id_fk` = `s`.`si_id_pk`
LEFT JOIN
`county`as `c` ON `tr`.`co_id_fk` = `c`.`co_id_pk`
LEFT JOIN
`vice_county`as `vc` ON `tr`.`vc_id_fk` = `vc`.`vc_id_pk`
LEFT JOIN
`habitat`as `h` ON `tr`.`hab_id_fk` = `h`.`hab_id_pk`
LEFT JOIN
(`record_attribute_data`as `rad`
INNER JOIN `record_attribute`as `ra` ON (`rad`.`ra_id_fk` = `ra`.`ra_id_pk`)) ON (`tr`.`tr_id_pk` = `rad`.`tr_id_fk`)
WHERE
`r`.`rec_email` = 'some_email#somewhere.com'
GROUP BY `tr`.`tr_id_pk`;
What you wish to do is known as "pivoting" your data and is something for which some other RDBMS have native support, but MySQL does not (by design, as the developers feel that such manipulations belong in the presentation layer).
However, as you've hinted at, you can construct a rather horrible MySQL query to perform the pivoting operation manually (one needs to join the attributes tables to the query once for each output column):
SELECT tr.tr_id_pk, abundance, life_stage -- etc.
FROM taxon_record AS tr
LEFT JOIN (
SELECT rad.tr_id_fk, rad.rad_value AS abundance
FROM
record_attribute_data ra JOIN record_attribute rad
ON rad.ra_id_fk = ra.ra_id_pk
WHERE ra.ra_name = 'abundance'
) AS tAbundance ON tAbundance.tr_id_fk = tr.tr_id_pk
LEFT JOIN (
SELECT rad.tr_id_fk, rad.rad_value AS life_stage
FROM
record_attribute_data ra JOIN record_attribute rad
ON rad.ra_id_fk = ra.ra_id_pk
WHERE ra.ra_name = 'life_stage'
) AS tLife_Stage ON tLife_Stage.tr_id_fk = tr.tr_id_pk
-- etc.
If you choose to go down this path, you can make your life slightly easier by generating this query using either a looping construct in PHP or a prepared statement in MySQL.
Is the problem that you are fetching the same column twice under different names?:
`rad`.`rad_value` AS `abundance`,
`rad`.`rad_value` AS `life_stage`
Looks like you'll always get the same thing for abundance and life_stage that way.

Slow query - Multiple joins and a lot of data

I'm sure there is a better way I could be doing this. I have three main tables with large amounts of data to run through:
records_main, sales, and appointments. Each with close to 20,000 records.
I need to join these three tables as well as a few others that arn't two large.
$SQL = "SELECT DISTINCT appointments.id AS aid, appointments.date, appointments.estimate_price, appointments.next_action, appointments.next_action_date, appointments.result, appointments.result_type, appointments.notes,
customer.id AS cid, customer.homeowner1_fname, customer.homeowner1_lname, customer.address, customer.city, customer.state, customer.zipcode, customer.phone1, customer.phone1_type, customer.phone2, customer.phone2_type, customer.phone3, customer.phone3_type, customer.phone4, customer.phone4_type, customer.phone5, customer.phone5_type, customer.lead_source, customer.lead_category, customer.primary_interest, customer.secondary_interest, customer.additional_interest1, customer.additional_interest2,
originator.employee_id AS originator_employee_id,originator.fname AS originator_fname,originator.lname AS originator_lname,
setter.employee_id AS setter_employee_id,setter.fname AS setter_fname,setter.lname AS setter_lname,
resetter.employee_id AS resetter_employee_id, resetter.fname AS resetter_fname, resetter.lname AS resetter_lname,
salesrep.employee_id AS salesrep_employee_id, salesrep.fname AS salesrep_fname, salesrep.lname AS salesrep_lname,
salesrep2.employee_id AS salesrep2_employee_id, salesrep2.fname AS salesrep2_fname, salesrep2.lname AS salesrep2_lname
FROM
core_records_appointments as appointments
INNER JOIN core_records_main as customer ON appointments.customer = customer.id
LEFT JOIN core_employees_main as originator ON appointments.originator = originator.id
LEFT JOIN core_employees_main as setter ON appointments.setter = setter.id
LEFT JOIN core_employees_main as resetter ON appointments.resetter = resetter.id
LEFT JOIN core_employees_main as salesrep ON appointments.sales_representative = salesrep.id
LEFT JOIN core_employees_main as salesrep2 ON appointments.sales_representative2 = salesrep2.id
";
This takes a few seconds but finally does load. The last join I put though seems to break the query together:
LEFT JOIN core_records_sales as sales ON appointments.day = sales.day_sold AND appointments.customer = sales.customer
After this I have a limit set and a group by
Anything I can do to improve this? I am using this with jqgrid, not sure if that helps
As a first approach, try to execute the query on the database using the EXPLAIN syntax. This will give you an analysis of the statement and tells you, if it uses indexes at all. If it doesn't use indexes or not enough indexes, try adding them to the tables.
Have you tried giving index on all the columns you are LEFT JOINing on?
TRY giving index to all these if they are not already declared as index

Categories