I have reverse engineered a minimal verifiable example on db-fiddle.com based on your question and answer details.
Using my reduced and generic sample data with the sql in your answer, the output is: (DB Fiddle Demo)
value |
field_id |
value |
field_id |
id |
title |
alias |
introtext |
fulltext |
catid |
field_id |
item_id |
value |
documentary |
417 |
2021-05-05 |
46 |
5 |
test 5 |
test-5 |
intro text 5 |
The full text 5 |
2 |
418 |
5 |
Andreas Soraru |
science-fiction |
417 |
2021-01-01 |
46 |
1 |
test 1 |
test-1 |
intro text 1 |
The full text 1 |
2 |
418 |
1 |
Andreas Soraru |
science-fiction |
417 |
2021-03-03 |
46 |
3 |
test 3 |
test-3 |
intro text 3 |
The full text 3 |
2 |
418 |
3 |
Andreas Soraru |
This is selecting all articles where catid = 2
and the author's name (field_id = 418
) contains Soraru
, then it sorts by genre (field_id = 417
) ASC, then release date (field_id = 46
). You state that this works for you, but let me show you a cleaner, more modern, and less bloated way of gathering and sorting this data...
- I do not recommend using old-skool comma-JOINs as you are using to relate the content table to the fields_values table.
- Use a pivot technique instead of making multiple JOINs. This table is often gigantic and the fewer times you need to join the whole table in your sql, the better.
- Don't put data in your SELECT clause unless you need it. Those duplicated
field_id
columns are going to overwrite each other and you don't actually need them -- let's clear them away. I am going to assume that you need those duplicated value
columns, so let's give them unique aliases so that you can access them.
- It is appropriate to use an INNER JOIN in this case because the HAVING clause necessitates the existance of related data in the fields_values table.
New / Recommended SQL: (DB Fiddle Demo)
SELECT lmnop_content.*,
MAX(IF(field_id = 418, value, NULL)) AS author,
MAX(IF(field_id = 417, value, NULL)) AS genre,
MAX(IF(field_id = 46, value, NULL)) AS release_date
FROM lmnop_content
INNER JOIN lmnop_fields_values ON id = item_id
WHERE catid = 2
GROUP BY id
HAVING MAX(IF(field_id = 418, value, NULL)) LIKE '%Soraru%'
ORDER BY genre, release_date
id |
title |
alias |
introtext |
fulltext |
catid |
author |
genre |
release_date |
5 |
test 5 |
test-5 |
intro text 5 |
The full text 5 |
2 |
Andreas Soraru |
documentary |
2021-05-05 |
1 |
test 1 |
test-1 |
intro text 1 |
The full text 1 |
2 |
Andreas Soraru |
science-fiction |
2021-01-01 |
3 |
test 3 |
test-3 |
intro text 3 |
The full text 3 |
2 |
Andreas Soraru |
science-fiction |
2021-03-03 |
This new script is much cleaner, readable, and maintainable.
The Joomla query builder syntax should look something like this: (I didn't take the time to test this)
$db = Factory::getDbo();
$query = $db->getQuery(true);
$query->select(
[
"#__content.*",
"MAX(IF(field_id = 418, value, NULL)) AS author",
"MAX(IF(field_id = 417, value, NULL)) AS genre",
"MAX(IF(field_id = 46, value, NULL)) AS release_date"
]
)
->from("#__content")
->innerJoin("#__fields_values ON id = item_id")
->where("cat_id = " . (int)$catid)
->group("id")
->having("MAX(IF(field_id = 418, value, NULL)) LIKE " . $db->q("%" . $db->escape($sorttype , true) . "%", false))
->order("genre, release_date");
$db->setQuery($query);
// var_export($db->loadAssocList());
#__fields_values
table? I don't see areleasedate
in the content table. You may need a pivot. If you would like me to help with this, I will need a dbfiddle demo link to play with. For example, see how Gart and I exchanged dbfiddle links here: joomla.stackexchange.com/q/28243/12352#__fields_values
table is set up. I have a long track record of answering all of the questions on JSE that incorporate this table. The challenge is, can you provide the dbfiddle link containing enough sample data from both tables before I go to bed? When you can produce the fiddle, please add it to your question as an edit. Here is the meta link often referred to on StackOverflow when a schema is beneficial: meta.stackoverflow.com/a/333953/2943403