SQL relationships, multiple methods, same result? Select, From, Where OR Select, From, Join, Where
If you only want to get the answers, don't involve the questions table.
Just select from the answers.
Adding unused tables into your query makes no sense at all -
It makes the query harder to read, thus harder to maintain,
and It makes the database work harder (though modern databases might just optimize the unused parts of the query away) to get the same results.
What's the purpose of a JOIN where no column from 2nd table is being used?
- Join (any inner, left or right) can duplicate rows if join key in joined dataset is not unique. For example if
a
contains single row withc_id=1
andb
contains two rows withc_id=1
, the result will be two rows witha.c_id=1
. - Join (inner) can filter rows if join key is absent in joined dataset. I believe this is what it meant to do.
If the goal is to get only rows with keys present in both datasets(filter) and you do not want duplication, and you do not use columns from joined dataset, then better use LEFT SEMI JOIN instead of JOIN, it will work as filter only even if there are duplicated keys in joined dataset:
left semi join (
select c_id from second
) b on a.c_id = b.c_id
This is much safer way to filter rows only which exist in both a and b and avoid unintended duplication.
You can replace join with WHERE IN/EXISTS, but it makes no difference, it is implemented as the same JOIN, check the EXPLAIN output and you will see the same query plan. Better use LEFT SEMI JOIN, it implements uncorrelated IN/EXISTS in efficient way.
If you prefer to move it to the WHERE:
WHERE a.c_id IN (select c_id from second)
or correlated EXISTS:
WHERE EXISTS (select 1 from second b where a.c_id=b.c_id)
But as I said, all of them are implemented internally using JOIN operator.
Mysql Left Join Case When
You can't do a case/when join as you have here. Since you have a split way of doing the HTML link references, and each has its own context of a biblio record, you might be best to get the pieces from two distinct queries of biblio vs non-biblio and UNION them. Take that result and apply to your concat process. Something like
SELECT
PQ.action_id,
PQ.barcode,
CONCAT( '<a href=\"/cgi-bin/koha/catalogue/detail.pl?biblionumber=',
PQ.biblionumber, '\">', b.title, '</a>') Title,
PQ.author,
PQ.timestamp,
CONCAT( '<a href=\"/cgi-bin/koha/members/moremember.pl?borrowernumber=',
b.borrowernumber, '\">', b.surname, ', ',
b.firstname, '</a>') Librarian,
PQ.permanent_location,
PQ.typeofentry,
PQ.action as type_of_action,
PQ.info
from
(
SELECT
action_id,
i.barcode,
biblio.biblionumber,
biblio.author,
al.timestamp,
i.permanent_location,
'biblio' typeofentry,
al.action,
al.info,
al.user
from
action_logs al
LEFT JOIN items i
on al.object = i.itemnumber
LEFT JOIN biblio
on al.object = biblio.biblionumber
where
al.info like 'biblio%'
UNION ALL
SELECT
action_id,
i.barcode,
biblio.biblionumber,
biblio.author,
al.timestamp,
i.permanent_location,
'item' typeofentry,
al.action,
al.info,
al.user
from
action_logs al
LEFT JOIN items i
on al.object = i.itemnumber
LEFT JOIN biblio
on i.biblionumber = biblio.biblionumber
where
NOT al.info like 'biblio%'
) PQ
LEFT JOIN borrowers b
ON PQ.user = b.borrowernumber
Join queries properly - SQL
Select the books and join the co-author count:
select
b.title,
case when b.author is null then 0 else 1 end as has_author,
coalesce(c.cnt, 0) as count_co_author
from books b
left outer join
(
select book, count(*) as cnt
from co_author
group by book
) c on c.book = b.isbn
order by b.title;
Or select from books and get the co-author count in a subquery:
select
b.title,
case when b.author is null then 0 else 1 end as has_author,
(
select count(*)
from co_author c
where c.book = b.isbn
) as count_co_author
from books b
order by b.title;
Related Topics
How to Limit the Number of Rows Returned by an Oracle Query After Ordering
Difference Between Union and Union All
Passing a Varchar Full of Comma Delimited Values to a SQL Server in Function
How to Make SQL Case Sensitive String Comparison on MySQL
Count the Number of Occurrences of a String in a Varchar Field
Conversion Failed When Converting Date And/Or Time from Character String While Inserting Datetime
Group by Clause in MySQL and Postgresql, Why the Error in Postgresql
Listagg Function: "Result of String Concatenation Is Too Long"
MySQL Update Column With Value from Another Table
Is There an Advantage to Varchar(500) Over Varchar(8000)
What Is the Most Efficient/Elegant Way to Parse a Flat Table into a Tree
Identity Increment Is Jumping in SQL Server Database
Get a List of Dates Between Two Dates
How to Do the Recursive Select Query in MySQL
Can You Use an Alias in the Where Clause in MySQL
Quick Selection of a Random Row from a Large Table in MySQL
Add a Column With a Default Value to an Existing Table in SQL Server