MySQL excutes select after where clause - mysql

This query gives an error unknown column company in where clause. I found that where clause runs first and select runs next. That could be the error here. But i dont know how to correct this in order to get company in result set.
SELECT trnsdriverid,
name,
(SELECT transcompany.name
FROM transcompany,
transcompdriver
WHERE transcompany.trnscompid = transcompdriver.trnscompid) AS 'company',
address,
dob,
license,
telephone
FROM transcompdriver
WHERE ? LIKE 'All'
OR name LIKE '%"+keyword+"%'
OR company LIKE '%"+keyword+"%'
OR trnsdriverid LIKE '%"+keyword+"%'

You can't reference column aliases in where statements. You should rewrite this query to use a JOIN and then do your filtering on the actual TransCompany.name column, for example:
select
d.trnsDriverID
,d.name
,c.name as [Company]
,d.address
,d.dob
,d.license
,d.telephone
from
TransCompDriver d
join
TransCompany c
on
c.trnscompid = d.trnscompid
where
? = 'All'
or
d.name like '%" + keyword + "%'
or
c.name like '%" + keyword + "%'
or
d.trnsDriverID like '%" + keyword + "%'
Also, don't use LIKE where a simple equality operator would do. I changed the query above to use = 'All'.

You should really be doing this using a join rather than a subselect. I would recommend this:
SELECT
d.trnsDriverID,
d.name,
c.name AS `company`,
d.address,
d.dob,
d.license,
d.telephone
FROM
TransCompDriver AS d
INNER JOIN TransCompany AS c
ON d.trnsCompID = c.trnsCompID
WHERE
? like 'All'
OR d.name LIKE '%"+keyword+"%'
OR `company` LIKE '%"+keyword+"%'
OR d.trnsDriverID LIKE '%"+keyword+"%'

The sub-query that pulls the column "company" does not have matching number of rows, try the join statement instead
select trnsDriverID, name, t1.name AS company, address, dob, license, telephone
from TransCompDriver JOIN (select trnsDriverID, name,
(select TransCompany.name from TransCompany LEFT JOIN TransCompDriver
ON TransCompany.trnsCompID=TransCompDriver.trnsCompID) AS t1
where ? like 'All' or name like '%"+keyword+"%' or company like '%"+keyword+"%'
or trnsDriverID like '%"+keyword+"%'

Related

Ordering mysql query results by location

I've a search bar to search for other users by their name or username, and that's easy to do, but what I'm trying to do is that in case more that one user have the same name that you're searching for I want to show first the closest one to you, so that first will appear the users with that name who are in the same city as u, then the same country, and then the rest of the world, I'am able to achieve the required result with multiple queries, but is it achievable with one query?
NOTE: the user table that I'm using for the search contains Username, FName, LName, CountryCode, CityID.
these are the queries I'm using now:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and user.CITYID = User's_City_ID
GROUP by user.USERNAME
ORDER by Avg_Rating
then I use the same query but for the country of the user and excluding the previously used city:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and user.CountryCode = User's_Country_Code and not user.CITYID = User's_City_ID
GROUP by user.USERNAME
ORDER by Avg_Rating
and then the same but excluding the whole country that I used in the prev. query:
Select user.USERNAME, AVG(userrating.RATING) as Avg_Rating
from user LEFT JOIN userrating on user.USERNAME = userrating.USERNAME
WHERE CONCAT (user.FNAME, " ", user.LNAME) like '%Searched Name%' and not user.CountryCode = User's_Country_Code
GROUP by user.USERNAME
ORDER by Avg_Rating
and then I'm combining the results of the three queries.
Starting from your current query (called « other » in the below SQL), you want to JOIN on the record that corresponds to the current user (called « me ») and then use a special ORDER BY clause to show the closest matching records first, using a CASE construct.
This assumes that « username » can be used to uniquely identify the current user.
SELECT
other.username
FROM userrating other
INNER JOIN userrating me on me.username = 'bar'
WHERE
CONCAT (other.FNAME, " ", other.LNAME) like '%Searched Name%'
ORDER BY
CASE
WHEN other.cityid = me.cityid THEN 0
WHEN other.countryid = me.countryid THEN 1
ELSE 2
END,
other.username
You need to replace 'bar' with current username.
It's difficult to do this exactly with one query, but you can do something like this:
SELECT * FROM users WHERE username LIKE '%searchkey%' OR fname LIKE '%searchkey%' OR lname LIKE '%searchkey%' OR countryid LIKE '%searchkey%' OR cityid LIKE '%searchkey%'
Here you can read more about the LIKE Operator.

mysql group concat unknow column error

I am trying to search for query on first name and last name field
here is my query
SELECT d.title, GROUP_CONCAT(u.firstName,' ',u.lastName) as fullname
FROM DEALS d
left JOIN USER u ON u.idUser = d.userId
WHERE ((d.title LIKE '%goutham%' OR d.keywords LIKE '%goutham%')
OR fullname LIKE '%goutham%') AND d.isPublic=1
But i got
Unknown column 'fullname' in 'where clause'
The immediate cause of your problem is that you can't refer to an alias defined in the SELECT clause in the WHERE clause of the same query. The solution would be to repeat the entire expression instead of using the alias. However, based on your comment, you really want to check the first name, so do just that:
SELECT
d.title,
CONCAT(u.firstName, ' ', u.lastName) AS fullname
FROM DEALS d
LEFT JOIN USER u
ON u.idUser = d.userId
WHERE
(d.title LIKE '%goutham%' OR
d.keywords LIKE '%goutham%' OR
u.firstName LIKE '%goutham%') AND d.isPublic = 1;
You cannot use a column alias in where. It has nothing to do with the rest of your query.
You don't have a GROUP BY, so I suspect GROUP_CONCAT() is not intended. Instead you want CONCAT(). You can repeat the expression in the WHERE, but I think you should look in each component:
SELECT d.title, CONCAT(u.firstName, ' ', u.lastName) as fullname
FROM DEALS d left JOIN USER
u
ON u.idUser = d.userId
WHERE (d.title LIKE '%goutham%' OR
d.keywords LIKE '%goutham%' OR
u.firstName LIKE '%goutham%' OR
u.lastName LIKE '%goutham%'
) AND
d.isPublic = 1;
If you care about performance and are looking for words, then you might want to look into MySQL's full text index capabilities.
If you still want to look on the combination, I would recommend repeating the expression:
WHERE (d.title LIKE '%goutham%' OR
d.keywords LIKE '%goutham%' OR
CONCAT(u.firstName, ' ', u.lastName) LIKE '%goutham%'
) AND
d.isPublic = 1;

counting overall results with groups in mysql

I see some questions that get at issues similar to this one, but I can't find any that quite catch it.
I'm working with this query:
SELECT COUNT(a.word) FROM concordance a, bigdic b
WHERE a.word = b.word
and a.word LIKE '%" . $name . "%'"
It works fine as it is, but I want to eliminate cases where word is duplicated in table b. If I add GROUP BY b.word, the query returns the count of the first group instead of the overall count minus the duplicates, whereas the right total would be the count of the groups. How do I get that total instead?
Select distinct words from b in a subquery and then join the result back to a, in this way only the unique words from b will be joined to a.
SELECT
COUNT(a.word)
FROM concordance a
JOIN (SELECT DISTINCT b.word
FROM bigdic b) temp
ON temp.word = a.word
WHERE a.word LIKE '%" . $name . "%'"
It can be more efficient to phrase this as an exists query:
SELECT COUNT(a.word)
FROM concordance a
WHERE a.word LIKE '%" . $name . "%'"
WHERE exists (select 1 from bigdic b.word = b.word);
Particularly if you have an index on bigdic(word).

SQL Server 2008 GROUP BY

I am stuck and I am trying to find a solution, so please help!
I have 3 tables:
Books (id, title, ...)
Authors (id, name, surname, ...)
book_authors (bookID, authorID, whatisdoing)
Now I want to retrieve all books depending on the title (user search) and all the other info (author name, surname). But, I want the book titles to be unique with only the first occurrence of the book_authors.whatisdoing to be shown.
In MS Access I achieved that with first function, but now first does not work and with min I didn't get the results I want.
Any help would be appreciate.
The query in Access was:
SELECT
First(book_authos.whatisdoing) AS FirstOfidiothta_ID,
First(authors.name) AS onoma,
First(authors.surname) AS eponymo,
books.ID, books.title, books.photoLink
FROM (books
INNER JOIN book_authors ON books.ID = book_authors.book_ID)
INNER JOIN authors ON book_authors.author_ID = authors.ID
GROUP BY
books.ID, books.titlos, books.photoLink, books.active
HAVING
(((books.titlos) Like '%" & textString & "%') AND
((books.active)=True) AND ((First(authors.active))=True))
ORDER BY
First(book_authos.whatisdoing), books.title
EDIT: Changed based on OP comments.
EDIT 2: Revised to correct flaws.
You might give this a try.
SELECT aba.name, aba.surname, aba.whatisdoing,
b.ID, b.title, b.photoLink
FROM Books b
JOIN
(
SELECT ba.bookID, ba.whatisdoing, a.name, a.surname,
ROW_NUMBER() OVER (PARTITION BY ba.bookID ORDER BY ba.whatisdoing) AS sequence
FROM book_authors ba
JOIN Authors a ON ba.authorID = a.id
WHERE a.active = 1
) AS aba ON b.id = aba.bookID
WHERE b.title LIKE '%' + #textString + '%'
AND b.active = 1
AND aba.sequence = 1
The ROW_NUMBER function assigns a row number to the row based on the groups defined in the PARTITION BY clause and the order defined by the ORDER BY clause.
#textString is a SQL Server variable. I'm not sure how you would assign this in your situation.
The boolean data type is BIT in SQL Server and the values are 0 for false and 1 from true.

mysql select where count = 0

In my db, I have a "sales" table and a "sales_item". Sometimes, something goes wrong and the sale is recorded but not the sales item's.
So I'm trying to get the salesID from my table "sales" that haven't got any rows in the sales_item table.
Here's the mysql query I thought would work, but it doesn't:
SELECT s.*
FROM sales s NATURAL JOIN sales_item si
WHERE s.date like '" . ((isset($_GET['date'])) ? $_GET['date'] : date("Y-m-d")) . "%'
AND s.sales_id like '" . ((isset($_GET['shop'])) ? $_GET['shop'] : substr($_COOKIE['shop'], 0, 3)) ."%'
HAVING count(si.sales_item_id) = 0;
Any thoughts?
Where does the table alias v does come from?
Showing the table definition would be a really good idea ;)
It has to be a left join:
SELECT *
FROM table1
LEFT JOIN table2 ON(table1.id = table2.table1_id)
WHERE table2.table1_id IS NULL
Table1 is your sales-Table and table2 is you sales_item
Having always used with Group By
GROUP BY si.sales_item_id
HAVING count(si.sales_item_id) = 0;
You don't need to join the tables, you can use something like:
[...] WHERE sales.id NOT IN (SELECT sales_id FROM sales_item)
This filters only the sales that do not have any corresponding sales_item entries.
For completeness ....
SELECT S.*
FROM SALES S
WHERE NOT EXISTS (
SELECT 1
FROM SALES_ITEM SI
WHERE SI.SALES_ITEM_ID = S.ID)
MySQL can have issues with IN clauses.
Assuming that each item in sales_item has an associated sales_id against it, you are probably looking for all sales that have no items.
How about using a subquery? Get all the sales_ids from the sales table where the id does not exist in the items table...
SELECT * from sales where sales_id not in (SELECT DISTINCT sales_id from sales_item)
(note : Exact syntax may be wrong, but the idea should be sound, if I understood the question correctly)
The join is restricting the rows to be displayed.
My advice is to forget about the join and use instead something like this:
select *
from sales
where salesId not in (select salesId from sales_item)
Basically, returns sales that doesn't have any associated sales_item.
Good luck
You should probably group rows by sales item id.
SELECT s.id, count(*) as no_of_items
FROM sales s NATURAL JOIN sales_item si
WHERE s.date like '" . ((isset($_GET['date'])) ? $_GET['date'] : date("Y-m-d")) . "%'
AND v.sales_id like '" . ((isset($_GET['shop'])) ? $_GET['shop'] : substr($_COOKIE['shop'], 0, 3)) ."%'
GROUP BY si.salesitem_id
HAVING no_of_items = 0;