Show rows with highest number, even if it's the same - php

I'm using the following SQL
SELECT
testjob.id AS id,
testjob.EndTime AS Date,
testsuitecollectionname,
testsuitecollection,
TestSuiteName,
TestSuite
FROM
Testreportingdebug.testjob
LEFT JOIN
testsuitecollection ON testsuitecollection.id = testjob.testsuitecollectionid
LEFT JOIN
testsuitecollectionlink ON testsuitecollection.id = testsuitecollectionlink.testsuitecollection
LEFT JOIN
testsuite ON testsuite.id = testsuitecollectionlink.testsuite
WHERE
testjob.Engine = 'SeqZap'
AND TestSuiteName IN (
'AlertManagement')
AND testjob.EndTime IN ('2020-05-18 05:18:58','7305', '2020-03-18 04:57:31', 'gin_mixit_simulated', '34', 'AlertManagement', '987'
, '2020-05-17 16:39:03', '2020-03-03 18:07:28', '2020-05-18 16:07:44')
AND testjob.id IN ('13382', '13372', '5921', '13391', '7305')
ORDER BY TestSuiteName;
and I get the following
Rows from table
Is it possible to filter this table so I get only the rows marked here:
Wanted rows
NOTE: I can have multiple TestSuiteNames, and they have to always with the highest date, and show all rows for it.
Could it be possible to use MAX(testjob.EndTime), and then if there is more than one Max date for that specific TestSuiteName, then it shows them, instead not showing?

SELECT
testjob.id AS id,
testjob.EndTime AS Date,
testsuitecollectionname,
testsuitecollection,
TestSuiteName,
TestSuite
FROM
Testreportingdebug.testjob
LEFT JOIN
testsuitecollection ON testsuitecollection.id = testjob.testsuitecollectionid
LEFT JOIN
testsuitecollectionlink ON testsuitecollection.id = testsuitecollectionlink.testsuitecollection
LEFT JOIN
testsuite ON testsuite.id = testsuitecollectionlink.testsuite
WHERE
testjob.Engine = 'SeqZap'
AND TestSuiteName IN (
'AlertManagement')
AND testjob.EndTime IN ('2020-05-18 05:18:58','7305', '2020-03-18 04:57:31', 'gin_mixit_simulated', '34', 'AlertManagement', '987'
, '2020-05-17 16:39:03', '2020-03-03 18:07:28', '2020-05-18 16:07:44')
AND testjob.id IN ('13382', '13372', '5921', '13391', '7305')
AND testsuitecollectionname = 'ceops1_pwm64_circ1'
ORDER BY TestSuiteName;
How about that?
Added (one line above Order by):
AND testsuitecollectionname = 'ceops1_pwm64_circ1'

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

JOIN Query while loading comments

I'm loading comments for product with id = '3'
$get_comments = mysql_query("SELECT * FROM products_comments WHERE product_id = '3'");
Now I want to add the "report abuse" option for each comment, for this purpose I'm having another table as "abuse_reports" which user abuse reports will be stored in this table, now if a user reported a comment, the report abuse option should not be there for that comment for that user there anymore, for this I'm doing:
while($row = mysql_fetch_array($get_comments)){
echo blah blah blah // comment details
// now for checking if this user should be able to report this or not, i make this query again:
$check_report_status = mysql_query("SELECT COUNT(id) FROM abuse_reports WHERE reporter_user_id = '$this_user_id' AND product_id = 'this_product_id'");
// blah blah count the abuse reports which the current user made for this product
if($count == 0) echo "<a>report abuse</a>";
}
With the above code, for each comment I'm making a new query, and that's obviously wrong, how I should join the second query with the first one?
Thanks
Updated query (that is working now, commited by questioner)
SELECT pc. * , count( ar.`id` ) AS `abuse_count`
FROM `products_comments` pc
LEFT OUTER JOIN `abuse_reports` ar ON pc.`id` = ar.`section_details`
AND ar.`reporter_id` = '$user_id'
WHERE pc.`product_id` = '$product_id'
GROUP BY pc.`id`
LIMIT 0 , 30
The query works as follow: You select all the fields of your products_comments with the given product_id but you also count the entries of abuse_reports for the given product_id. Now you LEFT JOIN the abuse_reports, which means that you access that table and hang it on to the left (your products_comments table). The OUTER allows that there is no need for a value in the abuse_reports table, so if there is no report you get null, and therefore a count of 0.
Please read this:
However, I needed to group the results, otherwise you get only one merged row as result. So please extend your products_comments with a field comment_id of type int that is the primary key and has auto_increment.
UPDATE: abuse count
Now you can do two things: By looping through the results, you can see for each single element if it has been reported by that user or not (that way you can hide abuse report links for example). If you want the overall number of reports, you just increase a counter variable which you declare outside the loop. Like this:
$abuse_counter = 0;
while($row = mysql....)
{
$abuse_counter += intval($row['abuse_count']); // this is 1 or 0
// do whatever else with that result row
}
echo 'The amount of reports: '.$abuse_counter;
Just a primitive sample
I believe your looking for a query something like this.
SELECT pc.*, COUNT(ar.*)
FROM products_comments AS pc
LEFT JOIN abuse_reports AS ar ON reporter_user_id = pc.user_id AND ar.product_id = pc.product_id
WHERE product_id = '3'"
try this SQL
SELECT pc.*, COUNT(ar.id) AS abuse_count
FROM products_comments pc
LEFT JOIN abuse_reports ar ON pc.product_id = ar.product_id
WHERE pc.product_id = '3' AND ar.reporter_user_id = '$this_user_id'
GROUP BY pc.product_id
The result is list of products_comments with abuse_reports count if exist for reporter_user_id

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.

Categories