PHP Pdo Retrieves Duplicate Data

PDO returning incorrect, but duplicate, data. Key's not in database.

It's not duplicates, it's just the current FETCH_MODE you're using. To get as associative keys only you need to specify as such; by default it fetches as both.

Use like so:

$query->fetchAll(PDO::FETCH_NUM); // to fetch with numeric indexes
$query->fetchAll(PDO::FETCH_ASSOC); // to fetch with associative indexes

fetchAll docs

fetch docs

How to find duplicate array values from PDO fetchall?

You can fix that on your query side by selecting DISTINCT rows of JOB and SUFFIX column like below,

$result = $conn->prepare('SELECT DISTINCT JOB, SUFFIX FROM JOBS_IN_PROCESS_G');

OR if you want on PHP side after selecting rows from table then check this example , But I prefer first one as it is better to get only what you need from DB table.

PDO: Remove duplicates of the query's results

The first argument of your fetchAll call schould be PDO::FETCH_ASSOC

See http://php.net/manual/en/pdostatement.fetch.php

SQL query duplicated on PHP PDO and different from the result on phpmyadmin

You have 2 problems, the first which is the row being duplicated, this is down to fetch() defaulting to FETCH_BOTH, which means it will return both an associative set of data as well as a numerically indexed set of data (both with the same values). I usually use PDO::FETCH_ASSOC as this is just values indexed by column names.

The second is that you only retrieve 1 row, the call to fetch() would normally be in a loop...

$myQuery->execute();
while( $banner = $myQuery->fetch(PDO::FETCH_ASSOC)) {
// echo $banner['pt'];
var_dump($banner);
}

or set the default mode for fetch using

$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

Do this just after making the connection so that all calls to fetch() will give the same style.

Check PDO query for result and then reuse the data

$result->fetch() only fetches rows that haven't already been fetched. Since you fetched everything with $result->fetchAll(), there's nothing left.

If you want the first row, you can use:

$row = data[0];

If you want to process all the rows, use:

foreach ($data as $row)

Instead of fetching everything, you can use the rowCount() method.

if (!$result->rowCount()) {
echo "No data";
} else {
echo "Data found!";
}

There are caveats regarding the use of rowCount() with SELECT queries in PDO, but I think it generally works with MySQL.

MySQL : Get duplicate data for duplicate query fields

I am not able to think of a MYSQL query right now. But if perfomance is not of a concern, you can use some thing like

$thumb = "SELECT thumbnail from users WHERE id = ?";
$search = $con->prepare($thumb);

foreach($idsearch as $id) {
$search->execute(array($id));
$pics = $search->fetch(PDO::FETCH_ASSOC);
$search->closeCursor();
$thumbnail[] = $pic['thumbnail'];
}

PDO will compile the SQL Query and the execution will be faster than a normal sql query.

MySQL + PHP: Avoid duplicate result due to two results from joined table

You can use a GROUP_CONCAT to get your results down to two dimensions so you don't get duplicate albums merely to populate a styles dropdown.
Instead you'd group concat the styles and make it pretty using the new line character.

Your query would wind up looking something like this:

SELECT
trackID,
vinylID,
side,
trackArtist,
trackTitle,
notes,
GROUP_CONCAT(mKeyID SEPARATOR '\n') as 'mKeyIDs',
GROUP_CONCAT(mKey SEPARATOR '\n') as 'mKeys',
Camelot,
GROUP_CONCAT(styleID SEPARATOR '\n') AS 'styleIDs',
GROUP_CONCAT(styleName SEPARATOR '\n') AS 'styleNames'
FROM
vinyl_tracks vt
INNER JOIN
vinyl_keys vk ON vt.mKeyID = vk.mKeyID
INNER JOIN
vinyl_tracks_styles vts ON vt.trackID = vts.trackID
INNER JOIN
vinyl_styles vs ON vts.styleID = vs.styleID
GROUP BY
vt.trackID
WHERE
vinylID = :vinylID

I am grouping here by track id because that appears to be the criteria you are using to determine whether something is a duplicate or not. From there, I'm using GROUP_CONCAT with the new line separator to show all your styles affected by this group by in the same cell. Your PHP could refer to this cell, and explode on the new line character to get what it needs for populating the dropdown.

Make sure this query works directly on the database first to see if you need to make adjustments to it.

JSON approach:

Alternatively, if your MySQL version supports JSON_ARRAYAGG, you could use it instead of GROUP_CONCAT to accomplish the functionally equivalent behavior albeit the much cleaner:

SELECT
trackID,
vinylID,
side,
trackArtist,
trackTitle,
notes,
JSON_ARRAYAGG(mKeyID) AS 'mKeyIDs',
JSON_ARRAYAGG(mKey) AS 'mKeys',
Camelot,
JSON_ARRAYAGG(styleID) AS 'styleIDs',
JSON_ARRAYAGG(styleName) AS 'styleNames'
FROM
vinyl_tracks vt
INNER JOIN
vinyl_keys vk ON vt.mKeyID = vk.mKeyID
INNER JOIN
vinyl_tracks_styles vts ON vt.trackID = vts.trackID
INNER JOIN
vinyl_styles vs ON vts.styleID = vs.styleID
GROUP BY
vt.trackID
WHERE
vinylID = :vinylID

Then in your PHP you'd simply reference $row['styleIDs'] and $row['styleNames'] to generate the key=>value pair for each option used in your "Styles" dropdown.

For the musical "Keys" dropdown options, you'd reference $row['mKeyID'] and $row['mKeys'] to generate the key=>value pair for each option used in your "Keys" dropdown.

Update:

I set this up locally and see the problem the OP is running into. My query is fine. However when trying to display the dropdown, OP is running into a bug with his or her PHP looping logic. More specifically the following logic is faulty:

        foreach($styles as $style) {

// if there's a match, add "selected" to the option
if($track['styleIDs'] == $style['styleID']) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
}

Now that I understand what the OP is trying to do, let's just rewrite the entire mess. I have refactored the code. I have also tested this locally:

$tracksQuery = $db->prepare("SELECT vt.trackID, vt.vinylID, vt.side, vt.trackArtist, vt.trackTitle, vt.notes, vt.mKeyID, vk.mKey, vk.Camelot, 
GROUP_CONCAT(vts.styleID SEPARATOR ',') AS 'styleIDs'
FROM vinyl_tracks vt
INNER JOIN vinyl_keys vk ON vt.mKeyID = vk.mKeyID
LEFT JOIN vinyl_tracks_styles vts ON vt.trackID = vts.trackID
WHERE vt.vinylID = :vinylID
GROUP BY vt.trackID");
$tracksQuery->bindParam(':vinylID', $vinylID);
$tracksQuery->execute();
$tracks = $tracksQuery->fetchAll(\PDO::FETCH_ASSOC);

$allStylesQuery = $db->prepare("SELECT * FROM vinyl_styles ORDER BY styleID ASC");
$allStylesQuery->execute();
$styles = $allStylesQuery->fetchAll(PDO::FETCH_ASSOC);

$stylesSelector = "";

foreach($tracks as $track)
{

$stylesSelector .= "<select multiple=\"multiple\" class=\"form-control form-control-sm\" name=\"styleID[".$track['trackID']."][]\"><option> – </option>";
$trackStyleIDs = explode(',', $track['styleIDs']);
foreach($styles as $style)
{
$optionValue = $style['styleID'];
$optionText = $style['styleName'];
$optionSelected = in_array($optionValue, $trackStyleIDs) ? ' selected="selected"' : '';
$stylesSelector .= sprintf('<option value="%s"%s>%s</option>', $optionValue,$optionSelected,$optionText);
}

$stylesSelector .= "</select>";
}


Related Topics



Leave a reply



Submit