Selecting Distinct rows When there is a Logical OR with two columns - mysql

As the title suggests I have a MySQL query like this:
SELECT DISTINCT `friendly_url` FROM `post` WHERE `description` LIKE ? OR `heading` LIKE ? ORDER BY `friendly_url`
I have given the string '%' wild card in the parameters so that this works as a Search function. How ever, Say a user is searching for a common word like 'is' and it appears in both heading and description in the same post. Then this query returns the same post twice. I don't want that to happen, hence the 'DISTINCT'.
Why does this happen? Any way I can work around to make it work the way i want?

The query is not returning the same row twice. The predicates in the WHERE clause are evaulated against each row, and either the row is returned, or it's not. No combination of OR conditions is going to cause MySQL to return the "same row" multiple times.
If you are getting duplicate values of friendly_url, then you have multiple rows in the post table that have the same value for friendly_url. (i.e. friendly_url column is not unique in the post table.)
You don't have to use the DISTINCT keyword to remove duplicates from the resultset. You could remove the DISTINCT keyword, and add GROUP BY friendly_url before the ORDER BY clause.
To identify the "duplicated" values of friendly_url, and how many rows have that same value:
SELECT p.friendly_url
, COUNT(1)
FROM post p
GROUP BY p.friendly_url
HAVING COUNT(1) > 1

Related

Why are duplicate results returned even when distinct keyword is used?

When I run the following query, I am returned two entries with duplicate results. Why are duplicate results returned when I’m using distinct here? The primary keys are the house number, street name, and unit number.
SELECT distinct
house_num,
Street_name,
Unit_Designator,
Unit_Num
FROM voterinfo.voter_info
WHERE house_num = 420
AND street_name = "PARK"
AND Unit_Num = ''
AND Unit_Designator = '';
select distinct is a statement that ensures that the result set has no duplicate rows. That is, it filters out rows where every column is the same (and NULL values are considered equal).
It does not look at a subset of columns.
Sometimes, people use select distinct and don't realize that it applies to all columns. It is rather amusing when the first column is in parentheses -- as if parentheses make a difference (they don't).
Then, you might also have situations where values look the same but are not.
Consider this simple example where values differ by only a space as the end of string:
select distinct x
from (select 'a' as x union all
select 'a '
) y;
Here is a db<>fiddle with this example.
This returns two rows, not 1.
Without sample data it is hard to say which of these situations you are referring to. But the rows that you think are "identical" really are not.
For the fields with datatype as Char or similar ( Street_name,Unit_Designator) it is possible that there are spaces that aren't visible in the query editor that are to be removed by applying appropriate trimming logic.Please refer below link,
MySQL select fields containing leading or trailing whitespace

SQL statement for displaying unique values

Below is the data in my table:
TABLE:
abc-ac
abc-dc
aax-i
bcs-o-dc
ddd-o-poe-dc
I need to write a query which will display only the unique entries as a result:
abc-ac
aax-i
bcs-o-dc
ddd-o-poe-dc
So basically, since the first two entries start with "abc", it should be treated as one and displayed.
Thanks.
If you're not picky about which one of the two abc-* records that it shows you can use this:
SELECT f1 FROM mytable GROUP BY substring_index(f1, '-', 1)
SQLFiddle Here
That substring_index() function will split the value in your field by - and return the first bit. So essentially your records get grouped by only the first part. This is one of the few times that we can take advantage of MySQLs strange GROUP BY behavior where it will allow you to leave out non-aggregated fields from the group by.

Where clause with one column and multiple criteria returning one row instead of13

I have a simple query with a few rows and multiple criteria in the where clause but it is only returning one row instead of 13. No joins and the syntax was triple checked and appears to be free of errors.
Query:
select column1, column2, column3
from mydb
where onecolumn in (number1, number2....number13)
Results:
returns one row of data associated with a random number in the where clause
spent a big part of the day trying to figure this one out and am now out of ideas. Please help...
Absent a more detailed test case, and the actual SQL statement that is actually running, this question cannot be answered. Here are some "ideas"...
Our first guess is that the rows you think are going to satisfy the predicates aren't actually satisfying all of the conditions.
Our second guess is that you've got an aggregate expression (COUNT(), MAX(), SUM()) in the SELECT list that's causing an implicit GROUP BY. This is a common "gotcha"... the non-standard MySQL extension to GROUP BY which allows non-aggregates to appear in the SELECT list, which are not also included as expressions in the GROUP BY clause. This same gotcha appears when the GROUP BY clause is omitted entirely, and an aggregate is included in the SELECT list.
But the question doesn't make any mention of an aggregate expression in the SELECT list.
Our third guess is another issue that beginners frequently overlook: the order of precedence of operations, especially AND and OR. For example, consider the expressions:
a AND b OR c
a AND ( b OR c )
( a AND b ) OR c
consider those while we sing-along, Sesame Street style,...: "One of these things is not like the others, one of these things just doesn't belong..."
A fourth guess... if it wasn't for the row being returned having a value of onecolumn as a random number in the IN list... if it was instead the first number in the IN list, we'd be very suspicious that the IN list actually contains a single string value that looks like a list a values, but is actually not.
The two expression in the SELECT list look very similar, but they are very different:
SELECT t.n IN (2,3,5,7) AS n_in_list
, t.n IN ('2,3,5,7') AS n_in_string
FROM ( SELECT 2 AS n
UNION ALL SELECT 3
UNION ALL SELECT 5
) t
The first expression is comparing n to each value in a list of four values.
The second expression is equivalent to t.n IN (2).
This is a frequent trip up when neophytes are dynamically creating SQL text, thinking that they can pass in a string value and that MySQL will see the commas within the string as part of the SQL statement.
(But this doesn't explain how a some the random one in the list.)
Those are all just guesses. Those are some of the most frequent trip ups we see, but we're just guessing. It could be something else entirely. In it's current form, there is no definitive "answer" to the question.

MySQL : Count returning double the number of entries when using distinct

So I do a count like so
select distinct count(prod.id) from product as prod....
I get back 175590
I do a select like so
select distinct prod.id from product as prod.... (rest of the query is exactly the same)
and I limit it. Now if I limit the query to return anything over the half way point it returns nothing. It appears as if count is returning double the number of entries each time.
Does anyone know of anything that may be causing this?
Thanks
Tracey
The DISTINCT keyword tells MySQL to strip the duplicate rows from the result set. Because SELECT COUNT(prod.id) returns a single row (I guess this, I cannot tell for sure until I see the complete query), adding DISTINCT in front of COUNT() does not change its behaviour in any way.
What you probably want is SELECT COUNT(DISTINCT prod.id) and that's a totally different thing. It removes the duplicate values of prod.id before counting them.
Your first query is counting how many prod.id's there are.
Your second query is showing all distinct prod.id's.
This is quite different.
If you were to do the second query without the distinct key word the number would be the same.

MySQL returns fewer rows with GROUP BY statement

I've got a MySQL database that stores image information. Right now it only has three rows stored in the database, and each row is associated with something like, for instance, a unique blog post via a key column.
As of right now, one "blog post key" has one image, and one has two images in the database.
When I run this query, MySQL returns all three rows.
SELECT `id`, `key`, `url`
FROM (`images`)
WHERE `key` = 'TpaS4G5h'
OR `key` = '78855e44'
However, when i add the GROUP BY statement I only get two rows... one for each key.
SELECT `id`, `key`, `url`
FROM (`images`)
WHERE `key` = 'TpaS4G5h'
OR `key` = '78855e44'
GROUP BY `key`
I'm sure there is a simple solution, but I don't know what it is... so any help would be really appreciated.
Thanks in advance!
GROUP BY groups all rows with the group by value into a single row, so it's doing exactly what it's supposed to. If you want the rows with the same key to be returned in consecutive rows, do an ORDER BY instead.
You don't need a group by for this query! Group by groups identical values for the selected column into a single row.
You are specifying two keys in the first query and returning three rows which means you have at list one duplicate in your key column. To validate this if you do a
select distinct key from images
you should only see two rows. This means if you group by this column all results that have this key in common will be rolled up in the result explaining the behavior you are seeing.
GROUP BY is used to "collapse" any rows which match the grouping criteria into a single row, so you can use the aggregate functions on them. SUM(), COUNT(), etc..
If you mean you want to group the records so that you that you can retrieve all the images associated with each key in a single fetchrow call, well, that's not what GROUP BY is for. You're trying to convert multi-row based data sets into a single row. If all you were trying to do was retrieve the IDs of those images, and do it in a single fetch per row, you could use something like
SELECT key, group_concat(id)
FROM images
WHERE key=XXX or key=YYY
GROUP BY key
That would give you a data set that looks like this:
key group_concat(id)
------------------------
xxx 100,101
yyy 102,103
but that would require post-processing in your script to seperate those concat'd IDs into seperate numbers.