mysql group by any one or more of several fields - php

I am looking to group by the following criteria:
so lets say I have how can I group them all
product1,brand1,null,null,12,null,1234
product2,brand1,null,null,12,null,null
product3,brand2,null,null,null,1234
product1,brand1,null,null,null,null,null
(product_name AND brand_name) upc or isbn or mpn or ean or model_number
is it possible to create a single select statement to return these grouped values ?
Many thanks in advance

The short answer is "No." How would MySQL know which one you want to group by in a particular situation? It wouldn't. You need to send MySQL a different SQL query for each situation.
If in your UI the user chose to group by one thing, send MySQL a query to group by that. If they chose to group by something else, send MySQL a query to group by that. You have to choose in PHP before you tell MySQL what to do. You can't expect MySQL to read your mind and know "in this case he wants to group by X."
You can, however, group by all those fields, giving them a priority. I.e. group by this one first, then by that one, etc. Like:
SELECT * from products
group by
product_name, brand_name,
upc, isbn, mpn, ean, model_number
But this is not going to group by one or the other. It will group by all of them, giving first priority to the first mentioned.

Related

PHP/SQL: Prevent Option values from repeating

So I am trying to create a query that shows the list of all the dates customers came in to order food. However, since there were multiple customers for a particular day and thats how the values have been stored in the table, whenever I turn the following query:-
SELECT DateOfEntry FROM KFC;
Although it works and I see all the details, I dont want the same date value to repeat. For example if Two customers A and B, came in on 11/11/17 to order food, I would get the result of the above mentioned query with two records of same date. I dont want the same dates to repeat. What do I do?
I know DISTINCT works but the problem is, I am creating a php page where admins can check the list of all the users who came in on a particular day. So I am using the select and option methods of HTML to select a date which then shows the list of the users who made an entry that day. With this code, only one record is shown
Try:
SELECT DISTINCT DateOfEntry FROM KFC;
Try :
SELECT DISTINCT DateOfEntry FROM KFC;
or this
SELECT DateOfEntry FROM KFC
GROUP BY DateOfEntry;

SELECT DISTINCT still showing duplicates

Yes, there's a thousand questions about this on SO, but I've been searching for half an hour and I've yet to find a solution.
So, I've a table like this:
And this is my query:
SELECT DISTINCT rengasID,leveys FROM renkaat ORDER BY leveys ASC
And this is the result I get:
If you get the idea, I'm populating a select field with it, but it still has duplicates.
What am I doing wrong?
If you want distinct leveys, just choose that field:
SELECT DISTINCT leveys
FROM renkaat
ORDER BY leveys ASC
The rengasid has a different value on each row.
The distinct clause applies to all the columns being returned, regardless of parentheses.
EDIT:
If you need the regasid in the result, then use group by:
select leveys, min(regasid) as regasid
from renkaat
group by leveys
order by leveys asc;
This gives the first id. If you need all of them, you can get them in a list using group_concat(). If you need a separate id on each row, well, then you have duplicates.
Your rengasID is still different in each shown line. The distinct will check a mix of every selected field, so in this case it will search a distinct combination of rengasID and leveys.
You cannot ask for your ID here, since MySQL has no way of knowing which one you want.
Depending on what you want to do it can be more correct to save your "leveys" (I'm not sure what they are) in a separate table with a unique ID and join it. For filling up your list with all possible leveys, you can just query that new table.
This can be important because using group by, you can get random results for id's later on.
This is because you are selecting combination of rengasID and leveys. And what you are getting as a result is a distinct combination of the two.
To achieve what you are trying, see the answer of #GordonLinoff.

Is there anyway to tell which fields are grouped fields in a MySQL result (PHP)

I have some PHP code that will run user-generated SQL on a MySQL table. The query possibilities are limited, but could be, for example
SELECT City, Country, count(*) FROM Table ... GROUP BY City, Country
or
SELECT count(*) AS Count, Role, Country FROM Table ... GROUP BY Role, Country
or
SELECT count(*), TicketType, City, SUM(Quantity) AS 'Total Quantity' FROM Table ... GROUP BY TicketType, City
and so on.
When presenting the results of the query, I want to take one type of action if the column is an grouped field (e.g. COUNT or SUM or AVG etc.)
Other than parsing the query, is there any way to determine which fields are grouped fields from the result set? I am using mysqli and PHP
it is simple I guess, the only fields you can select in SELECT clause are the fields that are either grouped in Group By clause or grouped by aggregated functions.
So when you use
SELECT City, Country, count(*) FROM Table ... GROUP BY City, Country
your result set will have multiple rows each with three columns:city,country,count(*). city and country are the fields which are grouped by.
Generally the answer is no.
What you receive from the db are field names and values. Without parsing the original query you can't be sure which fields are aggregations and which are not.
Probably in your case there can be constraints you can use. For example:
If numbers can be only generated fields you can check the contents of the result. (Of course this is very unstable.)
Maybe you can use the field's name as a hint. Maybe it contains something related to aggregations. (sum, count, total,...)
But probably to best/most stable way to handle your problem to get more control around the query generation, and set explicit constraints you need or save the details you need later.
Maybe you can try to use this function: http://www.php.net/manual/en/pdostatement.getcolumnmeta.php
But I don't think it will be satisfying.

How do I retrieve data with MySQL such that I won't be getting duplicate values in a single column?

I am currently working on a school system where we have a parent course and a child course (meta_courses in Moodle).
So, we have a table mdl_course_meta and it has 3 fields. Id, parent_course and child_course.
My problem is that a parent course can have many child courses so that means, for example, a parent_course = 50 can appear two times in the table which means it has 2 child courses. I just want to be able to find all the parent courses without it returning the same value twice or more times. I'm currently using this query right now which obviously doesn't do what I want:
$q = "SELECT * FROM mdl_course_meta";
I am working with PHP as well by the way.
Thanks a lot.
SELECT DISTINCT parent_course from mdl_course_meta
That should do it if you just want the course names. One thing to keep in mind, if you want other fields this is not going to work the way you want it to(how would it know which record to choose if there are multiple records with the same parent_course and you only want one).
This approach can only be used if you only want to return the parent_courses without duplicates.
DISTINCT helps to eliminate duplicates. If a query returns a result that contains duplicate rows, you can remove duplicates to produce a result set in which every row is unique. To do this, include the keyword DISTINCT after SELECT and before the output column list.
$q = "SELECT DISTINCT parent_course FROM mdl_course_meta";
If you don't want duplicate values in a single column, use GROUP BY parent_course.
In this way you are free to select any column.
If you only want distinct values for a particular column column, then you can use GROUP BY:
SELECT *
FROM mdl_course_meta
GROUP BY parent_course
The values in the other columns will be arbitrary. This will work in MySQL 5.x.
MySQL 4.x won't let you be arbitrary, so you can't mix aggregate and non-aggregate columns. Instead, you'd have to do something like this, which gets a bit complicated:
SELECT MAX(col1), MAX(col2), parent_course, MAX(col4), ...
FROM mdl_course_meta
GROUP BY parent_course
This way, the values aren't arbitrary. You've specified the ones you want.

Mysql Unique Query

I have a programme listing database with all the information needed for one programme packed into one table (I should have split programmes and episodes into their own) Now since there are multiple episodes for any given show I wish to display the main page with just the title names in ascending and chosen letter. Now I know how to do the basic query but this is all i know
SELECT DISTINCT title FROM programme_table WHERE title LIKE '$letter%'
I know that works i use it. But I am using a dynamic image loading that requires a series number to return that image full so how do I get the title to be distinct but also load the series number from that title?
I hope I have been clear.
Thanks for any help
Paul
You can substitute the DISTINCT keyword for a GROUP BY clause.
SELECT
title
, series_number
FROM
programme_table
WHERE title LIKE '$letter%'
GROUP BY
title
, series_number
There are currently two other valid options:
The option suggested by Mohammad is to use a HAVING clause in stead of the WHERE clause this is actually less optimal:
The WHERE clause is used to restrict records, and is also used by the query optimizer to determine which indexes and tables to use. HAVING is a "filter" on the final result set, and is applied after ORDER BY and GROUP BY, so MySQL cannot use it to optimize the query.
So HAVING is a lot less optimal and you should only use it when you cannot use 'WHERE' to get your results.
quosoo points out that the DISTINCT keyword is valid for all listed columns in the query. This is true, but generally people do not recommend it (there is no performance difference *In some specific cases there is a performance difference***)**. The MySQL optimizer however spits out the same query for both so there is no actual performance difference.
Update
Although MySQL does apply the same optimization to both queries, there is actually a difference: when DISTINCT is used in combination with a LIMIT clause, MySQL stops as soon as it finds enough unique rows. so
SELECT DISTINCT
title
, series_number
FROM
programme_table
WHERE
title LIKE '$letter%'
is actually the best option.
select title,series_number from programme_table group by title,series_number having title like '$letter%';
DISTINCT keyword works actually for a list of colums so if you just add the series to your query it should return a set of unique title, series combinations:
SELECT DISTINCT title, series FROM programme_table WHERE title LIKE '$letter%'
Hey thanks for that but i have about 1000 entries with the same series so it would single out the series as well rendering about 999 programmes useless and donot show.
I however found out away to make it unique and show the series number
SELECT * FROM four a INNER JOIN (SELECT title, MIN(series) AS MinPid FROM four WHERE title LIKE '$letter%' GROUP BY title) b ON a.title = b.title AND a.series = b.MinPid
Hopefully it helps anyone in the future and thank you for the replies :)

Categories