To simplify the explanation, I will try to simplify everything.
I have three SQL tables: Users , Certs , Serv
The Users table stores information about unique users.
The Certs table stores information about certificates and the UserId of the user who has this certificate (1 user can have several certificates)
The Serv table stores data on marine services and the UserId user (for example, the Certs table, 1 user can have several entries in the Serv table)
SAMPLE DATA
Users
UserId Name 1 John 2 Lisa
Certs
Id UserId CertName 1 1 A 2 1 B 3 1 C 4 2 A 5 2 C
Serv
UserId Name 1 SA 1 SB 1 SC 1 SD 2 S2A
I need to get output through PHP, for example (where UserId = 1), and for reality there will be more columns from each table (for example, more detailed information about certificates, such as release date, expiration date, place of release, etc. on the):
Personal details: Name John Certificates: Certificate Id Certificate Name 1 A 2 B 3 C Sea Services: Sea Service Name SA SB SC SD
But I have incorrect output, duplicate entries, which is associated with the union of two tables with UserId , in which there are several records with this UserId .
PHP code
$users = $con->prepare(" select u.Name ,GROUP_CONCAT(c.Id SEPARATOR '<br>') AS Id ,GROUP_CONCAT(c.certsName SEPARATOR '<br>') AS certsName ,GROUP_CONCAT(s.Name SEPARATOR '<br>') AS Name from users u left join certs c on u.UserId = c.UserId left join serv s on u.UserId = s.UserId where u.UserId = ? "); $users->bind_param('i', $GetUserId); $users->execute(); $users->bind_result( $userName, $certId, $certName, $servName ); <?php while ($users->fetch()) { ?> <span>Personal Details</span> <div class="grid-group"> <div class="grid-column"> <div class="grid-item header">User Name </div> </div> <div class="grid-column"> <div class="grid-item"><?php echo $userName; ?></div> </div> </div> <span>Certificates</span> <div class="grid-group"> <div class="grid-column"> <div class="grid-item header">Certificate Id</div> <div class="grid-item header">Certificate Name</div> </div> <div class="grid-column"> <div class="grid-item"><?php echo $certId; ?></div> <div class="grid-item"><?php echo $certName; ?></div> </div> </div> <span>Sea Services</span> <div class="grid-group"> <div class="grid-column"> <div class="grid-item header">Sea Service Name</div> </div> <div class="grid-column"> <div class="grid-item"><?php echo $servName; ?></div> </div> </div> <?php } ?>
You can check SQL FIDDLE to see which results are selected by duplicating rows.
Do you have any ideas how I can achieve the desired result without duplicates?
UPDATE
After using GROUP_CONCAT with DISTINCT This is still wrong. Imagine in a Serv table I have columns like: UserId , Name , Rank and Country
If the same user worked in different companies (this name in the example is the name of the company) with the same rating in different countries, he chooses the wrong data. For instance:
Services Table (SQL)
UserId Name Rank Country 1 SA Captain USA 1 SB Captain USA 1 SC Captain RUS 1 SD Captain ENG 2 S2A Engineer USA
If I use a query like this:
select u.Name ,GROUP_CONCAT(distinct c.Id SEPARATOR '<br>') AS Id ,GROUP_CONCAT(distinct c.certsName SEPARATOR '<br>') AS certsName ,GROUP_CONCAT(distinct s.Name SEPARATOR '<br>') AS Name ,GROUP_CONCAT(distinct s.Rank SEPARATOR '<br>') AS Rank ,GROUP_CONCAT(distinct s.Country SEPARATOR '<br>') AS Country from users u left join certs c on u.UserId = c.UserId left join serv s on u.UserId = s.UserId where u.UserId = ?
So GROUP_CONCAT(DISTINCT..) returns the following to me:
...... Sea Services: Sea Service Name Rank Country SA Captain USA SB RUS SC ENG SD
Only the first row has a rank, and the first 3 rows return countries, but the database stores the ranks and countries for each row.
The complete desired result with this data should be:
Personal details: Name John Certificates: Certificate Id Certificate Name 1 A 2 B 3 C Sea Services: Sea Service Name Rank Country SA Captain USA SB Captain USA SC Captain RUS SD Captain ENG
You can check it on SQL FIDDLE
UPDATE 2
If I remove DISTINCT , I get the following output:
Sea Service Name Rank Country SA Captain USA SA Captain USA SA Captain USA SB Captain USA SB Captain USA SB Captain USA SC Captain RUS SC Captain RUS SC Captain RUS SD Captain ENG SD Captain ENG SD Captain ENG
If I use DISTINCT , I get the following:
Sea Services: Sea Service Name Rank Country SA Captain USA SB RUS SC ENG SD
But it should be:
Sea Services: Sea Service Name Rank Country SA Captain USA SB Captain USA SC Captain RUS SD Captain ENG
UPDATE 3
Imagine that I have a fixed column width and I have a long Sea Service Name that will be wrapped to a new line:
Sea Service Name | Rank | Country -----------------|--------|--------- This is long Sea | Captain| USA Service Name |--------|--------- -----------------| Captain| RUS Other Name |--------|--------- -----------------| Captain| ENG Another long Sea |--------|--------- Service Name | Master | USA -----------------|--------|--------- Other Sea Serv | -----------------|
As you can see, each column is divided, rows do not match. But it should be like 1 row. So I think I can not achieve this with GROUP_CONCAT , it seems like I need a different way.
What it looks like in reality:
